summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h2
-rw-r--r--src/3rdparty/webkit/WebCore/WebCore.pro17
-rw-r--r--src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri4
-rw-r--r--src/corelib/concurrent/qfutureinterface.cpp2
-rw-r--r--src/corelib/global/global.pri7
-rw-r--r--src/corelib/global/qglobal.cpp131
-rw-r--r--src/corelib/global/qglobal.h31
-rw-r--r--src/corelib/global/qnamespace.h5
-rw-r--r--src/corelib/global/qnamespace.qdoc97
-rw-r--r--src/corelib/io/qdiriterator.cpp28
-rw-r--r--src/corelib/io/qiodevice.cpp9
-rw-r--r--src/corelib/io/qresource.cpp6
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp27
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h3
-rw-r--r--src/corelib/kernel/qtranslator.cpp13
-rw-r--r--src/corelib/plugin/qplugin.qdoc8
-rw-r--r--src/corelib/statemachine/qhistorystate.cpp3
-rw-r--r--src/corelib/thread/qthread_unix.cpp27
-rw-r--r--src/corelib/tools/qalgorithms.qdoc52
-rw-r--r--src/corelib/tools/qbytearray.cpp2
-rw-r--r--src/corelib/tools/qcache.qdoc6
-rw-r--r--src/corelib/tools/qiterator.qdoc80
-rw-r--r--src/corelib/tools/qmap.cpp2
-rw-r--r--src/corelib/tools/qpair.qdoc6
-rw-r--r--src/corelib/tools/qset.qdoc30
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc8
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflipable.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp6
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativerectangle.cpp10
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextlayout.cpp15
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextlayout_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp3
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp6
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp46
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp2
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp17
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h2
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp172
-rw-r--r--src/declarative/util/qdeclarativebehavior.cpp6
-rw-r--r--src/declarative/util/qdeclarativeconnections.cpp2
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp6
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp4
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp13
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation.cpp12
-rw-r--r--src/declarative/util/qdeclarativespringanimation.cpp20
-rw-r--r--src/declarative/util/qdeclarativestate.cpp4
-rw-r--r--src/declarative/util/qdeclarativestategroup.cpp6
-rw-r--r--src/declarative/util/qdeclarativetransition.cpp22
-rw-r--r--src/declarative/util/qdeclarativeview.cpp12
-rw-r--r--src/gui/dialogs/qabstractprintdialog.cpp18
-rw-r--r--src/gui/dialogs/qmessagebox.cpp48
-rw-r--r--src/gui/egl/qegl_symbian.cpp11
-rw-r--r--src/gui/embedded/qvfbhdr.h41
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp32
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h3
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp27
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h1
-rw-r--r--src/gui/gui.pro8
-rw-r--r--src/gui/image/image.pri15
-rw-r--r--src/gui/image/qicon.cpp13
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/image/qimagereader.cpp3
-rw-r--r--src/gui/image/qimagewriter.cpp3
-rw-r--r--src/gui/image/qnativeimagehandleprovider_p.h69
-rw-r--r--src/gui/image/qpixmap.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp3
-rw-r--r--src/gui/image/qpixmap_s60.cpp31
-rw-r--r--src/gui/image/qpixmapcache.cpp4
-rw-r--r--src/gui/image/qpixmapdata_p.h4
-rw-r--r--src/gui/image/qvolatileimage.cpp318
-rw-r--r--src/gui/image/qvolatileimage_p.h101
-rw-r--r--src/gui/image/qvolatileimagedata.cpp113
-rw-r--r--src/gui/image/qvolatileimagedata_p.h97
-rw-r--r--src/gui/image/qvolatileimagedata_symbian.cpp474
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h11
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp315
-rw-r--r--src/gui/inputmethod/qinputcontext.cpp7
-rw-r--r--src/gui/itemviews/qheaderview.cpp8
-rw-r--r--src/gui/itemviews/qlistwidget.cpp7
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp15
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.h1
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.cpp5
-rw-r--r--src/gui/itemviews/qtreeview.cpp11
-rw-r--r--src/gui/itemviews/qtreewidget.cpp6
-rw-r--r--src/gui/kernel/kernel.pri2
-rw-r--r--src/gui/kernel/qapplication.cpp17
-rw-r--r--src/gui/kernel/qapplication_p.h2
-rw-r--r--src/gui/kernel/qapplication_s60.cpp389
-rw-r--r--src/gui/kernel/qapplication_win.cpp34
-rw-r--r--src/gui/kernel/qclipboard_win.cpp15
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h18
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm2
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp164
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp31
-rw-r--r--src/gui/kernel/qsoftkeymanager_common_p.h3
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp12
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm1
-rw-r--r--src/gui/kernel/qt_s60_p.h174
-rw-r--r--src/gui/kernel/qwidget.cpp17
-rw-r--r--src/gui/kernel/qwidget_mac.mm14
-rw-r--r--src/gui/kernel/qwidget_p.h7
-rw-r--r--src/gui/kernel/qwidget_s60.cpp85
-rw-r--r--src/gui/painting/qbackingstore.cpp5
-rw-r--r--src/gui/painting/qbrush.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp4
-rw-r--r--src/gui/painting/qgraphicssystem.cpp5
-rw-r--r--src/gui/painting/qgraphicssystem_p.h2
-rw-r--r--src/gui/painting/qgraphicssystem_runtime.cpp6
-rw-r--r--src/gui/painting/qpaintengine_mac.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp7
-rw-r--r--src/gui/painting/qpaintengine_s60.cpp21
-rw-r--r--src/gui/painting/qpainter.cpp34
-rw-r--r--src/gui/painting/qpainterpath.cpp24
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp28
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp9
-rw-r--r--src/gui/styles/qs60style.cpp207
-rw-r--r--src/gui/styles/qs60style_p.h14
-rw-r--r--src/gui/styles/qs60style_s60.cpp103
-rw-r--r--src/gui/styles/qs60style_simulated.cpp7
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp7
-rw-r--r--src/gui/text/qfontengine_mac.mm19
-rw-r--r--src/gui/text/qfragmentmap_p.h5
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp2
-rw-r--r--src/gui/text/qtextengine.cpp21
-rw-r--r--src/gui/text/qtextengine_mac.cpp5
-rw-r--r--src/gui/text/qtextengine_p.h1
-rw-r--r--src/gui/text/qtextlayout.cpp66
-rw-r--r--src/gui/text/qtextobject.cpp7
-rw-r--r--src/gui/text/qtextobject.h2
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp2
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp2
-rw-r--r--src/gui/widgets/qabstractslider.cpp2
-rw-r--r--src/gui/widgets/qcombobox.cpp18
-rw-r--r--src/gui/widgets/qmenu.cpp36
-rw-r--r--src/gui/widgets/qscrollbar.cpp2
-rw-r--r--src/gui/widgets/qsplitter.cpp2
-rw-r--r--src/imports/gestures/qdeclarativegesturearea.cpp2
-rw-r--r--src/multimedia/audio/qaudioinput.cpp17
-rw-r--r--src/network/access/qftp.cpp4
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp15
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp18
-rw-r--r--src/network/access/qnetworkcookie.cpp21
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp7
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp20
-rw-r--r--src/network/bearer/qnetworksession.h5
-rw-r--r--src/network/bearer/qsharednetworksession.cpp9
-rw-r--r--src/network/kernel/qnetworkinterface_symbian.cpp2
-rw-r--r--src/network/ssl/qsslcertificate.cpp34
-rw-r--r--src/network/ssl/qsslcertificate_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp20
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp32
-rw-r--r--src/opengl/opengl.pro9
-rw-r--r--src/opengl/qgl.cpp21
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_egl.cpp27
-rw-r--r--src/opengl/qgl_symbian.cpp132
-rw-r--r--src/opengl/qglpaintdevice.cpp2
-rw-r--r--src/opengl/qgltexturepool.cpp244
-rw-r--r--src/opengl/qgltexturepool_p.h147
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp23
-rw-r--r--src/opengl/qgraphicssystem_gl_p.h4
-rw-r--r--src/opengl/qpixmapdata_gl.cpp159
-rw-r--r--src/opengl/qpixmapdata_gl_p.h68
-rw-r--r--src/opengl/qpixmapdata_poolgl.cpp936
-rw-r--r--src/opengl/qwindowsurface_gl.cpp141
-rw-r--r--src/openvg/qpaintengine_vg.cpp140
-rw-r--r--src/openvg/qpaintengine_vg_p.h2
-rw-r--r--src/openvg/qpixmapdata_vg.cpp182
-rw-r--r--src/openvg/qpixmapdata_vg_p.h28
-rw-r--r--src/openvg/qvg_symbian.cpp180
-rw-r--r--src/openvg/qvgfontglyphcache_p.h2
-rw-r--r--src/openvg/qvgimagepool.cpp15
-rw-r--r--src/openvg/qwindowsurface_vgegl.cpp5
-rw-r--r--src/plugins/audio/audio.pro3
-rw-r--r--src/plugins/bearer/icd/dbusdispatcher.cpp9
-rw-r--r--src/plugins/bearer/icd/qnetworksession_impl.cpp14
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp5
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp12
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp5
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp4
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp223
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h23
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp35
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h7
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp18
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h2
-rw-r--r--src/plugins/plugins.pro1
-rw-r--r--src/plugins/qpluginbase.pri2
-rw-r--r--src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pri16
-rw-r--r--src/qbase.pri2
-rw-r--r--src/qt3support/tools/q3asciidict.qdoc6
-rw-r--r--src/qt3support/tools/q3dict.qdoc4
-rw-r--r--src/qt3support/tools/q3intdict.qdoc6
-rw-r--r--src/qt3support/tools/q3memarray.qdoc8
-rw-r--r--src/qt3support/tools/q3ptrdict.qdoc6
-rw-r--r--src/qt3support/tools/q3ptrlist.qdoc10
-rw-r--r--src/qt3support/tools/q3valuelist.qdoc10
-rw-r--r--src/qt3support/tools/q3valuestack.qdoc2
-rw-r--r--src/qt3support/tools/q3valuevector.qdoc10
-rw-r--r--src/s60installs/bwins/QtGuiu.def29
-rw-r--r--src/s60installs/bwins/QtOpenGLu.def19
-rw-r--r--src/s60installs/bwins/QtOpenVGu.def10
-rw-r--r--src/s60installs/eabi/QtGuiu.def37
-rw-r--r--src/s60installs/eabi/QtOpenGLu.def17
-rw-r--r--src/s60installs/eabi/QtOpenVGu.def10
-rw-r--r--src/s60installs/qt.iby20
-rw-r--r--src/s60installs/s60installs.pro4
-rw-r--r--src/s60main/s60main.pro2
-rw-r--r--src/script/api/qscriptcontext.cpp10
-rw-r--r--src/script/api/qscriptengine.cpp31
-rw-r--r--src/script/api/qscriptvalue.cpp5
-rw-r--r--src/src.pro2
-rw-r--r--src/svg/qsvghandler.cpp2
-rw-r--r--src/testlib/qsignalspy.qdoc10
-rw-r--r--src/testlib/qtestevent.qdoc2
220 files changed, 6401 insertions, 1452 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h
index f8bace4..9349b48 100644
--- a/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h
+++ b/src/3rdparty/webkit/JavaScriptCore/wtf/MathExtras.h
@@ -190,7 +190,7 @@ inline float deg2turn(float d) { return d / 360.0f; }
inline float rad2grad(float r) { return r * 200.0f / piFloat; }
inline float grad2rad(float g) { return g * piFloat / 200.0f; }
-#if !COMPILER(MSVC) && !COMPILER(RVCT) && !OS(ANDROID) && !COMPILER(WINSCW)
+#if !COMPILER(MSVC) && !OS(ANDROID) && !OS(SYMBIAN)
using std::isfinite;
using std::isinf;
using std::isnan;
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro
index 37d216d..c70a168 100644
--- a/src/3rdparty/webkit/WebCore/WebCore.pro
+++ b/src/3rdparty/webkit/WebCore/WebCore.pro
@@ -37,15 +37,14 @@ symbian: {
# Need to guarantee that these come before system includes of /epoc32/include
MMP_RULES += "USERINCLUDE rendering"
MMP_RULES += "USERINCLUDE platform/text"
- symbian-abld|symbian-sbsv2 {
- # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target.
- # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000.
- QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000
- MMP_RULES += ALWAYS_BUILD_AS_ARM
- } else {
- QMAKE_CFLAGS -= --thumb
- QMAKE_CXXFLAGS -= --thumb
- }
+
+ # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target.
+ # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000.
+ QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000
+ QMAKE_LFLAGS.GCCE += -Tdata 0x1000000
+
+ CONFIG += do_not_build_as_thumb
+
CONFIG(release, debug|release): QMAKE_CXXFLAGS.ARMCC += -OTime -O3
}
diff --git a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri
index b98617f..3ec3e97 100644
--- a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri
+++ b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri
@@ -1,5 +1,5 @@
-QT_WEBKIT_VERSION = 4.7.2
+QT_WEBKIT_VERSION = 4.7.4
QT_WEBKIT_MAJOR_VERSION = 4
QT_WEBKIT_MINOR_VERSION = 7
-QT_WEBKIT_PATCH_VERSION = 2
+QT_WEBKIT_PATCH_VERSION = 4
QT_CONFIG += webkit
diff --git a/src/corelib/concurrent/qfutureinterface.cpp b/src/corelib/concurrent/qfutureinterface.cpp
index 627d0c7..c5bd802 100644
--- a/src/corelib/concurrent/qfutureinterface.cpp
+++ b/src/corelib/concurrent/qfutureinterface.cpp
@@ -219,7 +219,7 @@ QString QFutureInterfaceBase::progressText() const
bool QFutureInterfaceBase::isProgressUpdateNeeded() const
{
QMutexLocker locker(&d->m_mutex);
- return (d->progressTime.elapsed() > (1000 / MaxProgressEmitsPerSecond));
+ return !d->progressTime.isValid() || (d->progressTime.elapsed() > (1000 / MaxProgressEmitsPerSecond));
}
void QFutureInterfaceBase::reportStarted()
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 86800ef..8ff423e 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -19,13 +19,16 @@ INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
# Only used on platforms with CONFIG += precompile_header
PRECOMPILED_HEADER = global/qt_pch.h
-linux*:!static:!linux-armcc:!linux-gcce {
+linux*:!static:!symbian-armcc:!symbian-gcce {
QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate
prog=$$quote(if (/program interpreter: (.*)]/) { print $1; })
DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\"
}
# Compensate for lack of platform defines in Symbian3 and Symbian4
-symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_))
+symbian {
+ DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_)) \
+ S60_VERSION_$$upper($$replace(S60_VERSION,\\.,_))
+}
include(../../../tools/shared/symbian/epocroot.pri)
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 62d83cc..2cfd9cc 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -86,7 +86,6 @@
# include "private/qcore_symbian_p.h"
_LIT(qt_S60Filter, "Series60v?.*.sis");
-_LIT(qt_symbianFilter, "Symbianv*.sis");
_LIT(qt_symbianSystemInstallDir, "z:\\system\\install\\");
#endif
@@ -1198,10 +1197,12 @@ bool qSharedBuild()
\value SV_9_2 Symbian OS v9.2
\value SV_9_3 Symbian OS v9.3
\value SV_9_4 Symbian OS v9.4
- \value SV_SF_1 Symbian^1
+ \value SV_SF_1 S60 5th Edition (Symbian^1)
\value SV_SF_2 Symbian^2
- \value SV_SF_3 Symbian^3
- \value SV_SF_4 Symbian^4
+ \value SV_SF_3 Symbian^3 or Symbian Anna
+ \value SV_SF_4 \e{This enum value is deprecated.}
+ \value SV_API_5_3 Symbian/S60 API version 5.3 release
+ \value SV_API_5_4 Symbian/S60 API version 5.4 release
\value SV_Unknown An unknown and currently unsupported platform
\sa S60Version, WinVersion, MacVersion
@@ -1218,8 +1219,10 @@ bool qSharedBuild()
\value SV_S60_3_1 S60 3rd Edition Feature Pack 1
\value SV_S60_3_2 S60 3rd Edition Feature Pack 2
\value SV_S60_5_0 S60 5th Edition
- \value SV_S60_5_1 S60 5th Edition Feature Pack 1
- \value SV_S60_5_2 S60 5th Edition Feature Pack 2
+ \value SV_S60_5_1 \e{This enum value is deprecated.}
+ \value SV_S60_5_2 Symbian^3 and Symbian Anna
+ \value SV_S60_5_3 Symbian/S60 API version 5.3 release
+ \value SV_S60_5_4 Symbian/S60 API version 5.4 release
\value SV_S60_Unknown An unknown and currently unsupported platform
\omitvalue SV_S60_None
@@ -1815,12 +1818,10 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
#ifdef Q_OS_SYMBIAN
static QSysInfo::SymbianVersion cachedSymbianVersion = QSysInfo::SymbianVersion(-1);
+static QSysInfo::S60Version cachedS60Version = QSysInfo::S60Version(-1);
-QSysInfo::SymbianVersion QSysInfo::symbianVersion()
+static void symbianInitVersions()
{
- if (cachedSymbianVersion != -1)
- return cachedSymbianVersion;
-
// Use pure Symbian code, because if done using QDir, there will be a call back
// to this method, resulting doing this expensive operation twice before the cache kicks in.
// Pure Symbian code also makes this method ~10x faster, speeding up the application launch.
@@ -1828,21 +1829,8 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion()
TFindFile fileFinder(rfs);
CDir* contents;
- // Check for Symbian4
- TInt err = fileFinder.FindWildByDir(qt_symbianFilter, qt_symbianSystemInstallDir, contents);
- if (err == KErrNone) {
- QScopedPointer<CDir> contentsDeleter(contents);
- err = contents->Sort(EDescending|ESortByName);
- if (err == KErrNone && contents->Count() > 0 && (*contents)[0].iName.Length() >= 9) {
- TInt major = (*contents)[0].iName[8] - '0';
- if (major == 4) {
- return cachedSymbianVersion = SV_SF_4;
- }
- }
- }
-
- // Check for S60 and Symbian3 platforms, which use older .sis naming scheme
- err = fileFinder.FindWildByDir(qt_S60Filter, qt_symbianSystemInstallDir, contents);
+ // Check for platform version
+ TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_symbianSystemInstallDir, contents);
if (err == KErrNone) {
QScopedPointer<CDir> contentsDeleter(contents);
err = contents->Sort(EDescending|ESortByName);
@@ -1851,61 +1839,82 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion()
TInt minor = (*contents)[0].iName[11] - '0';
if (major == 3) {
if (minor == 1) {
- return cachedSymbianVersion = SV_9_2;
+ cachedS60Version = QSysInfo::SV_S60_3_1;
+ cachedSymbianVersion = QSysInfo::SV_9_2;
} else if (minor == 2) {
- return cachedSymbianVersion = SV_9_3;
+ cachedS60Version = QSysInfo::SV_S60_3_2;
+ cachedSymbianVersion = QSysInfo::SV_9_3;
}
} else if (major == 5) {
if (minor == 0) {
- return cachedSymbianVersion = SV_9_4;
- }
- else if (minor == 1) {
- return cachedSymbianVersion = SV_SF_2;
- }
- else if (minor == 2) {
- return cachedSymbianVersion = SV_SF_3;
+ cachedS60Version = QSysInfo::SV_S60_5_0;
+ cachedSymbianVersion = QSysInfo::SV_9_4;
+ } else if (minor == 1) {
+ cachedS60Version = QSysInfo::SV_S60_5_1;
+ cachedSymbianVersion = QSysInfo::SV_SF_2;
+ } else if (minor == 2) {
+ cachedS60Version = QSysInfo::SV_S60_5_2;
+ cachedSymbianVersion = QSysInfo::SV_SF_3;
+ } else if (minor == 3) {
+ cachedS60Version = QSysInfo::SV_S60_5_3;
+ cachedSymbianVersion = QSysInfo::SV_API_5_3;
+ } else if (minor >= 4) {
+ cachedS60Version = QSysInfo::SV_S60_5_4;
+ cachedSymbianVersion = QSysInfo::SV_API_5_4;
}
}
}
}
# ifdef Q_CC_NOKIAX86
- // Some emulator environments may not contain the version specific .sis files, so
- // simply hardcode the version on those environments. Note that can't use
- // SYMBIAN_VERSION_* defines for S60 3.x/5.0 platforms, as they do not define them
- // right anyway in case .sis files are not found.
+ if (cachedS60Version == -1) {
+ // Some emulator environments may not contain the version specific .sis files, so
+ // simply hardcode the version on those environments. Note that can't use
+ // S60_VERSION_* defines for S60 3.x/5.0 platforms, as they do not define them
+ // right anyway in case .sis files are not found.
# if defined(__SERIES60_31__)
- return cachedSymbianVersion = SV_9_2;
+ cachedS60Version = QSysInfo::SV_S60_3_1;
+ cachedSymbianVersion = QSysInfo::SV_9_2;
# elif defined(__S60_32__)
- return cachedSymbianVersion = SV_9_3;
+ cachedS60Version = QSysInfo::SV_S60_3_2;
+ cachedSymbianVersion = QSysInfo::SV_9_3;
# elif defined(__S60_50__)
- return cachedSymbianVersion = SV_9_4;
-# elif defined(SYMBIAN_VERSION_SYMBIAN3)
- return cachedSymbianVersion = SV_SF_3;
-# elif defined(SYMBIAN_VERSION_SYMBIAN4)
- return cachedSymbianVersion = SV_SF_4;
+ cachedS60Version = QSysInfo::SV_S60_5_0;
+ cachedSymbianVersion = QSysInfo::SV_9_4;
+# elif defined(S60_VERSION_5_2)
+ cachedS60Version = QSysInfo::SV_S60_5_2;
+ cachedSymbianVersion = QSysInfo::SV_SF_3;
+# elif defined(S60_VERSION_5_3)
+ cachedS60Version = QSysInfo::SV_S60_5_3;
+ cachedSymbianVersion = QSysInfo::SV_API_5_3;
+# elif defined(S60_VERSION_5_4)
+ cachedS60Version = QSysInfo::SV_S60_5_4;
+ cachedSymbianVersion = QSysInfo::SV_API_5_4;
# endif
+ }
# endif
- //If reaching here, it was not possible to determine the version
- return cachedSymbianVersion = SV_Unknown;
+
+ if (cachedS60Version == -1) {
+ //If reaching here, it was not possible to determine the version
+ cachedS60Version = QSysInfo::SV_S60_Unknown;
+ cachedSymbianVersion = QSysInfo::SV_Unknown;
+ }
+}
+
+QSysInfo::SymbianVersion QSysInfo::symbianVersion()
+{
+ if (cachedSymbianVersion == -1)
+ symbianInitVersions();
+
+ return cachedSymbianVersion;
}
QSysInfo::S60Version QSysInfo::s60Version()
{
- switch (symbianVersion()) {
- case SV_9_2:
- return SV_S60_3_1;
- case SV_9_3:
- return SV_S60_3_2;
- case SV_9_4:
- return SV_S60_5_0;
- case SV_SF_2:
- return SV_S60_5_1;
- case SV_SF_3:
- return SV_S60_5_2;
- default:
- return SV_S60_Unknown;
- }
+ if (cachedS60Version == -1)
+ symbianInitVersions();
+
+ return cachedS60Version;
}
#endif // ifdef Q_OS_SYMBIAN
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index c2fb16c..e5109e6 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -44,11 +44,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "4.7.2"
+#define QT_VERSION_STR "4.7.4"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x040702
+#define QT_VERSION 0x040704
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -284,7 +284,7 @@ namespace QT_NAMESPACE {}
# endif
#endif
-#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE)
+#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) && !defined(QT_BOOTSTRAPPED)
#error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration."
#endif
@@ -1524,7 +1524,9 @@ public:
SV_SF_1 = SV_9_4,
SV_SF_2 = 40,
SV_SF_3 = 50,
- SV_SF_4 = 60
+ SV_SF_4 = 60, // Deprecated
+ SV_API_5_3 = 70,
+ SV_API_5_4 = 80
};
static SymbianVersion symbianVersion();
enum S60Version {
@@ -1533,9 +1535,10 @@ public:
SV_S60_3_1 = SV_9_2,
SV_S60_3_2 = SV_9_3,
SV_S60_5_0 = SV_9_4,
- //versions beyond 5.0 are to be confirmed - it is better to use symbian version
- SV_S60_5_1 = SV_SF_2,
- SV_S60_5_2 = SV_SF_3
+ SV_S60_5_1 = SV_SF_2, // Deprecated
+ SV_S60_5_2 = SV_SF_3,
+ SV_S60_5_3 = SV_API_5_3,
+ SV_S60_5_4 = SV_API_5_4
};
static S60Version s60Version();
#endif
@@ -2446,9 +2449,21 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf();
# define QT_SYMBIAN_SUPPORTS_SGIMAGE
#endif
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#ifdef SYMBIAN_GRAPHICS_SET_SURFACE_TRANSPARENCY_AVAILABLE
# define Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
#endif
+
+#ifdef SYMBIAN_GRAPHICS_TRANSITION_EFFECTS_SIGNALING_AVAILABLE
+# define Q_SYMBIAN_TRANSITION_EFFECTS
+#endif
+#endif
+
+#ifdef SYMBIAN_WSERV_AND_CONE_MULTIPLE_SCREENS
+#define Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS
+#endif
+
+#ifdef SYMBIAN_GRAPHICS_FIXNATIVEORIENTATION
+#define Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION
#endif
//Symbian does not support data imports from a DLL
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 398f9bf..15cc809 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -526,6 +526,8 @@ public:
WA_X11DoNotAcceptFocus = 132,
+ WA_SymbianNoSystemRotation = 133,
+
// Add new attributes before this line
WA_AttributeCount
};
@@ -575,7 +577,8 @@ public:
PreferDither = 0x00000040,
AvoidDither = 0x00000080,
- NoOpaqueDetection = 0x00000100
+ NoOpaqueDetection = 0x00000100,
+ NoFormatConversion = 0x00000200
};
Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index d617f77..f03fb25 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -238,81 +238,25 @@
/*!
\enum Qt::GlobalColor
- \raw HTML
- <style type="text/css" id="colorstyles">
- #white { background-color: #ffffff; color: #000000 }
- #black { background-color: #000000; color: #ffffff }
- #red { background-color: #ff0000; color: #000000 }
- #darkRed { background-color: #800000; color: #ffffff }
- #green { background-color: #00ff00; color: #000000 }
- #darkGreen { background-color: #008000; color: #ffffff }
- #blue { background-color: #0000ff; color: #ffffff }
- #darkBlue { background-color: #000080; color: #ffffff }
- #cyan { background-color: #00ffff; color: #000000 }
- #darkCyan { background-color: #008080; color: #ffffff }
- #magenta { background-color: #ff00ff; color: #000000 }
- #darkMagenta { background-color: #800080; color: #ffffff }
- #yellow { background-color: #ffff00; color: #000000 }
- #darkYellow { background-color: #808000; color: #ffffff }
- #gray { background-color: #a0a0a4; color: #000000 }
- #darkGray { background-color: #808080; color: #ffffff }
- #lightGray { background-color: #c0c0c0; color: #000000 }
- </style>
- \endraw
-
Qt's predefined QColor objects:
- \value white \raw HTML
- White <tt id="white">(#ffffff)</tt>
- \endraw
- \value black \raw HTML
- Black <tt id="black">(#000000)</tt>
- \endraw
- \value red \raw HTML
- Red <tt id="red">(#ff0000)</tt>
- \endraw
- \value darkRed \raw HTML
- Dark red <tt id="darkRed">(#800000)</tt>
- \endraw
- \value green \raw HTML
- Green <tt id="green">(#00ff00)</tt>
- \endraw
- \value darkGreen \raw HTML
- Dark green <tt id="darkGreen">(#008000)</tt>
- \endraw
- \value blue \raw HTML
- Blue <tt id="blue">(#0000ff)</tt>
- \endraw
- \value darkBlue \raw HTML
- Dark blue <tt id="darkBlue">(#000080)</tt>
- \endraw
- \value cyan \raw HTML
- Cyan <tt id="cyan">(#00ffff)</tt>
- \endraw
- \value darkCyan \raw HTML
- Dark cyan <tt id="darkCyan">(#008080)</tt>
- \endraw
- \value magenta \raw HTML
- Magenta <tt id="magenta">(#ff00ff)</tt>
- \endraw
- \value darkMagenta \raw HTML
- Dark magenta <tt id="darkMagenta">(#800080)</tt>
- \endraw
- \value yellow \raw HTML
- Yellow <tt id="yellow">(#ffff00)</tt>
- \endraw
- \value darkYellow \raw HTML
- Dark yellow <tt id="darkYellow">(#808000)</tt>
- \endraw
- \value gray \raw HTML
- Gray <tt id="gray">(#a0a0a4)</tt>
- \endraw
- \value darkGray \raw HTML
- Dark gray <tt id="darkGray">(#808080)</tt>
- \endraw
- \value lightGray \raw HTML
- Light gray <tt id="lightGray">(#c0c0c0)</tt>
- \endraw
+ \value white \span {id="color-white"} {White (#ffffff) }
+ \value black \span {id="color-black"} {Black (#000000) }
+ \value red \span {id="color-red"} {Red (#ff0000) }
+ \value darkRed \span {id="color-darkRed"} {Dark red (#800000) }
+ \value green \span {id="color-green"} {Green (#00ff00) }
+ \value darkGreen \span {id="color-darkGreen"} {Dark green (#008000) }
+ \value blue \span {id="color-blue"} {Blue (#0000ff) }
+ \value darkBlue \span {id="color-darkBlue"} {Dark blue (#000080) }
+ \value cyan \span {id="color-cyan"} {Cyan (#00ffff) }
+ \value darkCyan \span {id="color-darkCyan"} {Dark cyan (#008080) }
+ \value magenta \span {id="color-magenta"} {Magenta (#ff00ff) }
+ \value darkMagenta \span {id="color-darkMagenta"} {Dark magenta (#800080) }
+ \value yellow \span {id="color-yellow"} {Yellow (#ffff00) }
+ \value darkYellow \span {id="color-darkYellow"} {Dark yellow (#808000) }
+ \value gray \span {id="color-gray"} {Gray (#a0a0a4) }
+ \value darkGray \span {id="color-darkGray"} {Dark gray (#808080) }
+ \value lightGray \span {id="color-lightGray"} {Light gray (#c0c0c0) }
\value transparent a transparent black value (i.e., QColor(0, 0, 0, 0))
\value color0 0 pixel value (for bitmaps)
\value color1 1 pixel value (for bitmaps)
@@ -739,6 +683,10 @@
until a non-opaque pixel is found, or if you want the pixmap to
retain an alpha channel for some other reason. If the image has no
alpha channel this flag has no effect.
+
+ \omitvalue NoFormatConversion Don't do any format conversions on the image.
+ Can be useful when converting a QImage to a QPixmap for a one-time
+ rendering operation for example.
*/
/*! \enum Qt::GUIStyle
@@ -1296,6 +1244,7 @@
\omitvalue WA_SetWindowModality
\omitvalue WA_WState_WindowOpacitySet
\omitvalue WA_WState_AcceptedTouchBeginEvent
+ \omitvalue WA_SymbianNoSystemRotation
*/
/*! \typedef Qt::HANDLE
@@ -2868,7 +2817,7 @@
INT_MIN, inclusive. For example, you can define custom priorities
as being relative to each other:
- \snippet doc/src/snippets/code/doc_src_qnamespace.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qnamespace.cpp 1
\sa QCoreApplication::postEvent()
*/
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 3b4adc3..4d3f50b 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -278,6 +278,7 @@ void QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo)
current entry will be returned as part of the directory iteration);
otherwise, false is returned.
*/
+
bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInfo &fi) const
{
Q_ASSERT(!fileName.isEmpty());
@@ -312,6 +313,14 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
return false;
}
#endif
+ // skip symlinks
+ const bool skipSymlinks = (filters & QDir::NoSymLinks);
+ const bool includeSystem = (filters & QDir::System);
+ if(skipSymlinks && fi.isSymLink()) {
+ // The only reason to save this file is if it is a broken link and we are requesting system files.
+ if(!includeSystem || fi.exists())
+ return false;
+ }
// filter hidden
const bool includeHidden = (filters & QDir::Hidden);
@@ -319,27 +328,20 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
return false;
// filter system files
- const bool includeSystem = (filters & QDir::System);
- if (!includeSystem && ((!fi.isFile() && !fi.isDir() && !fi.isSymLink())
+ if (!includeSystem && (!(fi.isFile() || fi.isDir() || fi.isSymLink())
|| (!fi.exists() && fi.isSymLink())))
return false;
// skip directories
const bool skipDirs = !(filters & (QDir::Dirs | QDir::AllDirs));
- if (skipDirs && fi.isDir()) {
- if (!((includeHidden && !dotOrDotDot && fi.isHidden())
- || (includeSystem && !fi.exists() && fi.isSymLink())))
- return false;
- }
+ if (skipDirs && fi.isDir())
+ return false;
// skip files
const bool skipFiles = !(filters & QDir::Files);
- const bool skipSymlinks = (filters & QDir::NoSymLinks);
- if ((skipFiles && (fi.isFile() || !fi.exists())) || (skipSymlinks && fi.isSymLink())) {
- if (!((includeHidden && !dotOrDotDot && fi.isHidden())
- || (includeSystem && !fi.exists() && fi.isSymLink())))
- return false;
- }
+ if (skipFiles && fi.isFile())
+ // Basically we need a reason not to exclude this file otherwise we just eliminate it.
+ return false;
// filter permissions
const bool filterPermissions = ((filters & QDir::PermissionMask)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 43e0f0d..7134ae9 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1628,10 +1628,11 @@ QString QIODevice::errorString() const
\fn qint64 QIODevice::readData(char *data, qint64 maxSize)
Reads up to \a maxSize bytes from the device into \a data, and
- returns the number of bytes read or -1 if an error occurred. If
- there are no bytes to be read, this function should return -1 if
- there can never be more bytes available (for example: socket
- closed, pipe closed, sub-process finished).
+ returns the number of bytes read or -1 if an error occurred.
+
+ If there are no bytes to be read and there can never be more bytes
+ available (examples include socket closed, pipe closed, sub-process
+ finished), this function returns -1.
This function is called by QIODevice. Reimplement this function
when creating a subclass of QIODevice.
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index d35d68e..207cda3 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -373,7 +373,7 @@ QResourcePrivate::ensureChildren() const
Constructs a QResource pointing to \a file. \a locale is used to
load a specific localization of a resource data.
- \sa QFileInfo, searchPaths(), setFileName(), setLocale()
+ \sa QFileInfo, QDir::searchPaths(), setFileName(), setLocale()
*/
QResource::QResource(const QString &file, const QLocale &locale) : d_ptr(new QResourcePrivate(this))
@@ -418,7 +418,7 @@ QLocale QResource::locale() const
/*!
Sets a QResource to point to \a file. \a file can either be absolute,
in which case it is opened directly, if relative then the file will be
- tried to be found in searchPaths().
+ tried to be found in QDir::searchPaths().
\sa absoluteFilePath()
*/
@@ -446,7 +446,7 @@ QString QResource::fileName() const
/*!
Returns the real path that this QResource represents, if the resource
- was found via the searchPaths() it will be indicated in the path.
+ was found via the QDir::searchPaths() it will be indicated in the path.
\sa fileName()
*/
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 47dd558..84825af 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -210,8 +210,10 @@ void QWakeUpActiveObject::RunL()
QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo)
: QActiveObject((timerInfo->interval) ? TIMER_PRIORITY : NULLTIMER_PRIORITY , dispatcher),
- m_timerInfo(timerInfo)
+ m_timerInfo(timerInfo), m_expectedTimeSinceLastEvent(0)
{
+ // start the timeout timer to ensure initialisation
+ m_timeoutTimer.start();
}
QTimerActiveObject::~QTimerActiveObject()
@@ -255,10 +257,23 @@ void QTimerActiveObject::StartTimer()
m_rTimer.After(iStatus, MAX_SYMBIAN_TIMEOUT_MS * 1000);
m_timerInfo->msLeft -= MAX_SYMBIAN_TIMEOUT_MS;
} else {
- //HighRes gives the 1ms accuracy expected by Qt, the +1 is to ensure that
- //"Timers will never time out earlier than the specified timeout value"
- //condition is always met.
- m_rTimer.HighRes(iStatus, (m_timerInfo->msLeft + 1) * 1000);
+ // this algorithm implements drift correction for repeating timers
+ // calculate how late we are for this event
+ int timeSinceLastEvent = m_timeoutTimer.restart();
+ int overshoot = timeSinceLastEvent - m_expectedTimeSinceLastEvent;
+ if (overshoot > m_timerInfo->msLeft) {
+ // we skipped a whole timeout, restart from here
+ overshoot = 0;
+ }
+ // calculate when the next event should happen
+ int waitTime = m_timerInfo->msLeft - overshoot;
+ m_expectedTimeSinceLastEvent = waitTime;
+ // limit the actual ms wait time to avoid wild corrections
+ // this will cause the real event time to slowly drift back to the expected event time
+ // measurements show that Symbian timers always fire 1 or 2 ms late
+ const int limit = 4;
+ waitTime = qMax(m_timerInfo->msLeft - limit, waitTime);
+ m_rTimer.HighRes(iStatus, waitTime * 1000);
m_timerInfo->msLeft = 0;
}
SetActive();
@@ -305,6 +320,8 @@ void QTimerActiveObject::Start()
if (!m_rTimer.Handle()) {
qt_symbian_throwIfError(m_rTimer.CreateLocal());
}
+ m_timeoutTimer.start();
+ m_expectedTimeSinceLastEvent = 0;
StartTimer();
} else {
iStatus = KRequestPending;
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index b785aea..a31a446 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -63,6 +63,7 @@
#include <qwaitcondition.h>
#include <qsocketnotifier.h>
#include <qdatetime.h>
+#include <qelapsedtimer.h>
#include <e32base.h>
@@ -143,6 +144,8 @@ private:
private:
SymbianTimerInfo *m_timerInfo;
+ QElapsedTimer m_timeoutTimer;
+ int m_expectedTimeSinceLastEvent;
RTimer m_rTimer;
};
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index d72c1ab..73a32c4 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -354,10 +354,15 @@ QTranslator::~QTranslator()
}
/*!
- Loads \a filename + \a suffix (".qm" if the \a suffix is
- not specified), which may be an absolute file name or relative
- to \a directory. Returns true if the translation is successfully
- loaded; otherwise returns false.
+
+ Loads \a filename + \a suffix (".qm" if the \a suffix is not
+ specified), which may be an absolute file name or relative to \a
+ directory. Returns true if the translation is successfully loaded;
+ otherwise returns false.
+
+ If \a directory is not specified, the directory of the
+ application's executable is used (i.e., as
+ \l{QCoreApplication::}{applicationDirPath()}).
The previous contents of this translator object are discarded.
diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc
index 54b2b38..7043fa0 100644
--- a/src/corelib/plugin/qplugin.qdoc
+++ b/src/corelib/plugin/qplugin.qdoc
@@ -51,7 +51,7 @@
If you want to use Q_DECLARE_INTERFACE with interface classes
declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE
is not inside a namespace though. For example:
- \snippet doc/src/snippets/code/doc_src_qplugin.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qplugin.cpp 0
\sa Q_INTERFACES(), Q_EXPORT_PLUGIN2(), {How to Create Qt Plugins}
*/
@@ -82,7 +82,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qplugin.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qplugin.cpp 1
See the \l{tools/plugandpaint}{Plug & Paint} example for details.
@@ -102,14 +102,14 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qplugin.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qplugin.cpp 2
Static plugins must also be included by the linker when your
application is built. For Qt's predefined plugins,
you can use the \c QTPLUGIN to add
the required plugins to your build. For example:
- \snippet doc/src/snippets/code/doc_src_qplugin.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qplugin.pro 3
\sa {Static Plugins}, {How to Create Qt Plugins}, {Using qmake}
*/
diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp
index 350c1a0..7093c32 100644
--- a/src/corelib/statemachine/qhistorystate.cpp
+++ b/src/corelib/statemachine/qhistorystate.cpp
@@ -168,6 +168,9 @@ QAbstractState *QHistoryState::defaultState() const
/*!
Sets this history state's default state to be the given \a state.
\a state must be a sibling of this history state.
+
+ Note that this function does not set \a state as the initial state
+ of its parent.
*/
void QHistoryState::setDefaultState(QAbstractState *state)
{
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 5177339..c2bc895 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -54,6 +54,11 @@
#include <private/qeventdispatcher_unix_p.h>
#endif
+#ifdef Q_OS_SYMBIAN
+#include <hal.h>
+#include <hal_data.h>
+#endif
+
#include "qthreadstorage.h"
#include "qthread_p.h"
@@ -63,6 +68,12 @@
#include <sched.h>
#include <errno.h>
+// You only find these enumerations on Symbian^3 onwards, so we need to provide our own
+// to remain compatible with older releases. They won't be called by pre-Sym^3 SDKs.
+
+// HALData::ENumCpus
+#define QT_HALData_ENumCpus 119
+
#ifdef Q_OS_BSD4
#include <sys/sysctl.h>
#endif
@@ -422,8 +433,20 @@ int QThread::idealThreadCount()
// as of aug 2008 Integrity only supports one single core CPU
cores = 1;
#elif defined(Q_OS_SYMBIAN)
- // ### TODO - Get the number of cores from HAL? when multicore architectures (SMP) are supported
- cores = 1;
+ if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) {
+ TInt inumcpus;
+ TInt err;
+ err = HAL::Get((HALData::TAttribute)QT_HALData_ENumCpus, inumcpus);
+ if (err != KErrNone) {
+ cores = 1;
+ } else if ( inumcpus <= 0 ) {
+ cores = 1;
+ } else {
+ cores = inumcpus;
+ }
+ } else {
+ cores = 1;
+ }
#elif defined(Q_OS_VXWORKS)
// VxWorks
# if defined(QT_VXWORKS_HAS_CPUSET)
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 34918a3..a9b7ddc 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -60,14 +60,14 @@
a particular value. If you need that functionality, you can use
qFill():
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 0
qFill() takes a begin iterator, an end iterator, and a value.
In the example above, we pass \c list.begin() and \c list.end()
as the begin and end iterators, but this doesn't have to be
the case:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 1
Different algorithms can have different requirements for the
iterators they accept. For example, qFill() accepts two
@@ -98,13 +98,13 @@
name_table array and return the corresponding Unicode value from
the \c value_table if the entity is recognized:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 2
This kind of code is for advanced users only; for most
applications, a QMap- or QHash-based approach would work just as
well:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 3
\section1 Types of Iterators
@@ -185,7 +185,7 @@
position \a begin2 + 1; and so on.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 4
\sa qCopyBackward(), {input iterators}, {output iterators}
*/
@@ -201,7 +201,7 @@
at position \a end2 - 2; and so on.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 5
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 5
\sa qCopy(), {bidirectional iterators}
*/
@@ -214,7 +214,7 @@
items compare equal; otherwise returns false.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 6
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 6
This function requires the item type (in the example above,
QString) to implement \c operator==().
@@ -228,7 +228,7 @@
Fills the range [\a begin, \a end) with \a value.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 7
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 7
\sa qCopy(), {forward iterators}
*/
@@ -249,7 +249,7 @@
value isn't found.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 8
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 8
This function requires the item type (in the example above,
QString) to implement \c operator==().
@@ -278,7 +278,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 9
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 9
This function requires the item type (in the example above,
\c int) to implement \c operator==().
@@ -302,7 +302,7 @@ of \a value in the variable passed as a reference in argument \a n.
Exchanges the values of variables \a var1 and \a var2.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 10
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 10
*/
/*! \fn void qSort(RandomAccessIterator begin, RandomAccessIterator end)
@@ -312,7 +312,7 @@ of \a value in the variable passed as a reference in argument \a n.
using the quicksort algorithm.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 11
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 11
The sort algorithm is efficient on large data sets. It operates
in \l {linear-logarithmic time}, O(\e{n} log \e{n}).
@@ -338,13 +338,13 @@ of \a value in the variable passed as a reference in argument \a n.
For example, here's how to sort the strings in a QStringList
in case-insensitive alphabetical order:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 12
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 12
To sort values in reverse order, pass
\l{qGreater()}{qGreater<T>()} as the \a lessThan parameter. For
example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 13
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 13
If neither of the two items is "less than" the other, the items are
taken to be equal. It is then undefined which one of the two
@@ -356,7 +356,7 @@ of \a value in the variable passed as a reference in argument \a n.
following code shows how to sort a list of strings case
insensitively using QMap:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 14
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 14
\sa QMap
*/
@@ -382,7 +382,7 @@ of \a value in the variable passed as a reference in argument \a n.
property is often useful when sorting user-visible data.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 15
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 15
The sort algorithm is efficient on large data sets. It operates
in \l {linear-logarithmic time}, O(\e{n} log \e{n}).
@@ -405,7 +405,7 @@ of \a value in the variable passed as a reference in argument \a n.
For example, here's how to sort the strings in a QStringList
in case-insensitive alphabetical order:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 16
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 16
Note that earlier versions of Qt allowed using a lessThan function that took its
arguments by non-const reference. From 4.3 and on this is no longer possible,
@@ -415,7 +415,7 @@ of \a value in the variable passed as a reference in argument \a n.
\l{qGreater()}{qGreater<T>()} as the \a lessThan parameter. For
example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 17
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 17
If neither of the two items is "less than" the other, the items are
taken to be equal. The item that appeared before the other in the
@@ -444,7 +444,7 @@ of \a value in the variable passed as a reference in argument \a n.
ascending order; see qSort().
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 18
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 18
This function requires the item type (in the example above,
\c{int}) to implement \c operator<().
@@ -452,7 +452,7 @@ of \a value in the variable passed as a reference in argument \a n.
qLowerBound() can be used in conjunction with qUpperBound() to
iterate over all occurrences of the same value:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 19
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 19
\sa qUpperBound(), qBinaryFind()
*/
@@ -494,7 +494,7 @@ of \a value in the variable passed as a reference in argument \a n.
ascending order; see qSort().
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 20
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 20
This function requires the item type (in the example above,
\c{int}) to implement \c operator<().
@@ -502,7 +502,7 @@ of \a value in the variable passed as a reference in argument \a n.
qUpperBound() can be used in conjunction with qLowerBound() to
iterate over all occurrences of the same value:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 21
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 21
\sa qLowerBound(), qBinaryFind()
*/
@@ -545,7 +545,7 @@ of \a value in the variable passed as a reference in argument \a n.
finer control.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 22
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 22
This function requires the item type (in the example above,
QString) to implement \c operator<().
@@ -587,7 +587,7 @@ of \a value in the variable passed as a reference in argument \a n.
example, \c{QWidget *}).
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 23
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 23
Notice that qDeleteAll() doesn't remove the items from the
container; it merely calls \c delete on them. In the example
@@ -618,7 +618,7 @@ of \a value in the variable passed as a reference in argument \a n.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 24
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 24
\sa {qGreater()}{qGreater<T>()}
*/
@@ -631,7 +631,7 @@ of \a value in the variable passed as a reference in argument \a n.
Example:
- \snippet doc/src/snippets/code/doc_src_qalgorithms.qdoc 25
+ \snippet doc/src/snippets/code/doc_src_qalgorithms.cpp 25
\sa {qLess()}{qLess<T>()}
*/
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 568293d..641f8d5 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -1363,7 +1363,7 @@ QByteArray::QByteArray(int size, Qt::Initialization)
If \a size is less than the current size, bytes are removed from
the end.
- \sa size()
+ \sa size(), truncate()
*/
void QByteArray::resize(int size)
diff --git a/src/corelib/tools/qcache.qdoc b/src/corelib/tools/qcache.qdoc
index 991238b..9e12c92 100644
--- a/src/corelib/tools/qcache.qdoc
+++ b/src/corelib/tools/qcache.qdoc
@@ -39,11 +39,11 @@
definition of a cache that stores objects of type Employee
associated with an integer key:
- \snippet doc/src/snippets/code/doc_src_qcache.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qcache.cpp 0
Here's how to insert an object in the cache:
- \snippet doc/src/snippets/code/doc_src_qcache.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qcache.cpp 1
The advantage of using QCache over some other key-based data
structure (such as QMap or QHash) is that QCache automatically
@@ -59,7 +59,7 @@
By default, QCache's maxCost() is 100. You can specify a
different value in the QCache constructor:
- \snippet doc/src/snippets/code/doc_src_qcache.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qcache.cpp 2
Each time you call insert(), you can specify a cost as third
argument (after the key and a pointer to the object to insert).
diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc
index d651343..6830442 100644
--- a/src/corelib/tools/qiterator.qdoc
+++ b/src/corelib/tools/qiterator.qdoc
@@ -50,7 +50,7 @@
the list (before the first item). Here's how to iterate over all
the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 0
The next() function returns the next item in the list and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -65,7 +65,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 1
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -98,7 +98,7 @@
beginning of the list (before the first item). Here's how to
iterate over all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 2
The next() function returns the next item in the list and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -113,7 +113,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 3
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -150,7 +150,7 @@
of the vector (before the first item). Here's how to iterate over
all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 4
The next() function returns the next item in the vector and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -165,7 +165,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 5
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 5
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -197,7 +197,7 @@
the first item). Here's how to iterate over all the elements
sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 6
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 6
The next() function returns the next item in the set and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -212,7 +212,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 7
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 7
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -251,7 +251,7 @@
of the list (before the first item). Here's how to iterate over
all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 8
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 8
The next() function returns the next item in the list and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -266,7 +266,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 9
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 9
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -277,7 +277,7 @@
insert().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 10
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 10
The example traverses a list, replacing negative numbers with
their absolute values, and eliminating zeroes.
@@ -312,7 +312,7 @@
beginning of the list (before the first item). Here's how to
iterate over all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 11
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 11
The next() function returns the next item in the list and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -327,7 +327,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 12
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 12
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -338,7 +338,7 @@
insert().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 13
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 13
The example traverses a list, replacing negative numbers with
their absolute values, and eliminating zeroes.
@@ -378,7 +378,7 @@
beginning of the list (before the first item). Here's how to
iterate over all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 14
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 14
The next() function returns the next item in the vector and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -393,7 +393,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 15
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 15
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop.
@@ -404,7 +404,7 @@
insert().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 16
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 16
The example traverses a vector, replacing negative numbers with
their absolute values, and eliminating zeroes.
@@ -440,7 +440,7 @@
of the set (before the first item). Here's how to iterate over
all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 17
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 17
The next() function returns the next item in the set and
advances the iterator. Unlike STL-style iterators, Java-style
@@ -455,7 +455,7 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 18
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 18
If you want to remove items as you iterate over the set, use
remove().
@@ -755,7 +755,7 @@
traversal functions (next(), previous(), findNext(), findPrevious()).
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 19
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 19
\sa insert(), setValue()
*/
@@ -766,7 +766,7 @@
traversal functions (next(), previous(), findNext(), findPrevious()).
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 20
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 20
\sa insert(), setValue()
*/
@@ -777,7 +777,7 @@
traversal functions (next(), previous(), findNext(), findPrevious()).
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 21
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 21
\sa insert(), setValue()
*/
@@ -788,7 +788,7 @@
traversal functions (next(), previous(), findNext(), findPrevious()).
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 22
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 22
\sa value()
*/
@@ -802,7 +802,7 @@
findPrevious().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 23
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 23
\sa value(), remove(), insert()
*/
@@ -816,7 +816,7 @@
findPrevious().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 24
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 24
\sa value(), remove(), insert()
*/
@@ -830,7 +830,7 @@
findPrevious().
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 25
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 25
\sa value(), remove(), insert()
*/
@@ -889,7 +889,7 @@
the map (before the first item). Here's how to iterate over all
the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 26
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 26
The next() function returns the next item in the map and
advances the iterator. The key() and value() functions return the
@@ -906,12 +906,12 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 27
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 27
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 28
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 28
Multiple iterators can be used on the same map. If the map is
modified while a QMapIterator is active, the QMapIterator will
@@ -941,7 +941,7 @@
the hash (before the first item). Here's how to iterate over all
the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 29
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 29
The next() function returns the next item in the hash and
advances the iterator. The key() and value() functions return the
@@ -958,12 +958,12 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 30
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 30
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 31
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 31
Multiple iterators can be used on the same hash. If the hash is
modified while a QHashIterator is active, the QHashIterator will
@@ -994,7 +994,7 @@
of the map (before the first item). Here's how to iterate over
all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 32
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 32
The next() function returns the next item in the map and
advances the iterator. The key() and value() functions return the
@@ -1011,12 +1011,12 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 33
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 33
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 34
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 34
If you want to remove items as you iterate over the map, use
remove(). If you want to modify the value of an item, use
@@ -1024,7 +1024,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 35
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 35
The example removes all (key, value) pairs where the key and the
value are the same.
@@ -1059,7 +1059,7 @@
of the hash (before the first item). Here's how to iterate over
all the elements sequentially:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 36
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 36
The next() function returns the next item in the hash and
advances the iterator. The key() and value() functions return the
@@ -1076,12 +1076,12 @@
Here's how to iterate over the elements in reverse order:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 37
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 37
If you want to find all occurrences of a particular value, use
findNext() or findPrevious() in a loop. For example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 38
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 38
If you want to remove items as you iterate over the hash, use
remove(). If you want to modify the value of an item, use
@@ -1089,7 +1089,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qiterator.qdoc 39
+ \snippet doc/src/snippets/code/doc_src_qiterator.cpp 39
The example removes all (key, value) pairs where the key and the
value are the same.
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index fe53374..2c028af 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -1073,7 +1073,7 @@ void QMapData::dump()
\overload
- The prefix -- operator (\c{--i}) makes the preceding item
+ The postfix -- operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previously
current item.
*/
diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc
index b900c4f..925100d 100644
--- a/src/corelib/tools/qpair.qdoc
+++ b/src/corelib/tools/qpair.qdoc
@@ -40,12 +40,12 @@
Here's an example of a QPair that stores one QString and one \c
double value:
- \snippet doc/src/snippets/code/doc_src_qpair.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qpair.cpp 0
The components are accessible as public data members called \l
first and \l second. For example:
- \snippet doc/src/snippets/code/doc_src_qpair.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qpair.cpp 1
QPair's template data types (T1 and T2) must be \l{assignable
data types}. You cannot, for example, store a QWidget as a value;
@@ -186,7 +186,7 @@
Returns a QPair\<T1, T2\> that contains \a value1 and \a value2.
Example:
- \snippet doc/src/snippets/code/doc_src_qpair.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qpair.cpp 2
This is equivalent to QPair<T1, T2>(\a value1, \a value2), but
usually requires less typing.
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index 011e9ee..5249182 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -40,19 +40,19 @@
Here's an example QSet with QString values:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 0
To insert a value into the set, use insert():
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 1
Another way to insert items into the set is to use operator<<():
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 2
To test whether an item belongs to the set or not, use contains():
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 3
If you want to navigate through all the values stored in a QSet,
you can use an iterator. QSet supports both \l{Java-style
@@ -60,18 +60,18 @@
iterators} (QSet::iterator and QSet::const_iterator). Here's how
to iterate over a QSet<QWidget *> using a Java-style iterator:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 4
Here's the same code, but using an STL-style iterator:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 5
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 5
QSet is unordered, so an iterator's sequence cannot be assumed to
be predictable. If ordering by key is required, use a QMap.
To navigate through a QSet, you can also use \l{foreach}:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 6
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 6
Items can be removed from the set using remove(). There is also a
clear() function that removes all items.
@@ -187,7 +187,7 @@
This function is useful for code that needs to build a huge set
and wants to avoid repeated reallocation. For example:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 7
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 7
Ideally, \a size should be slightly more than the maximum number
of elements expected in the set. \a size doesn't have to be prime,
@@ -603,18 +603,18 @@
start iterating. Here's a typical loop that prints all the items
stored in a set:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 8
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 8
Here's a loop that removes certain items (all those that start
with 'J') from a set while iterating:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 9
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 9
STL-style iterators can be used as arguments to \l{generic
algorithms}. For example, here's how to find an item in the set
using the qFind() algorithm:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 10
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 10
Multiple iterators can be used on the same set. However, you may
not attempt to modify the container while iterating on it.
@@ -646,13 +646,13 @@
start iterating. Here's a typical loop that prints all the items
stored in a set:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 11
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 11
STL-style iterators can be used as arguments to \l{generic
algorithms}. For example, here's how to find an item in the set
using the qFind() algorithm:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 12
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 12
Multiple iterators can be used on the same set. However, you may
not attempt to modify the container while iterating on it.
@@ -886,7 +886,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 13
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 13
\sa fromList(), QList::fromSet(), qSort()
*/
@@ -911,7 +911,7 @@
Example:
- \snippet doc/src/snippets/code/doc_src_qset.qdoc 14
+ \snippet doc/src/snippets/code/doc_src_qset.cpp 14
\sa toList(), QList::toSet()
*/
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index d68e8a1..996ca7f 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -35,12 +35,12 @@
The C++ language doesn't support variable-length arrays on the stack.
For example, the following code won't compile:
- \snippet doc/src/snippets/code/doc_src_qvarlengtharray.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qvarlengtharray.cpp 0
The alternative is to allocate the array on the heap (with
\c{new}):
- \snippet doc/src/snippets/code/doc_src_qvarlengtharray.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qvarlengtharray.cpp 1
However, if myfunc() is called very frequently from the
application's inner loop, heap allocation can be a major source
@@ -53,7 +53,7 @@
it is much faster than heap allocation.
Example:
- \snippet doc/src/snippets/code/doc_src_qvarlengtharray.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qvarlengtharray.cpp 2
In the example above, QVarLengthArray will preallocate 1024
elements on the stack and use them unless \c{n + 1} is greater
@@ -223,7 +223,7 @@
be used to access and modify the items in the array.
Example:
- \snippet doc/src/snippets/code/doc_src_qvarlengtharray.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qvarlengtharray.cpp 3
The pointer remains valid as long as the array isn't reallocated.
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index affb456..82ed18c 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -452,7 +452,7 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd()
\section1 Example Usage
- \div {float-right}
+ \div {class="float-right"}
\inlineimage flickable.gif
\enddiv
diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
index 5fda758..d23374b 100644
--- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
@@ -86,13 +86,13 @@ public:
The following example shows a Flipable item that flips whenever it is
clicked, rotating about the y-axis.
- This flipable item has a \c flipped boolean property that is toggled
- whenever the MouseArea within the flipable is clicked. When
- \c flipped is true, the item changes to the "back" state; in this
+ This flipable item has a \c flipped boolean property that is toggled
+ whenever the MouseArea within the flipable is clicked. When
+ \c flipped is true, the item changes to the "back" state; in this
state, the \c angle of the \l Rotation item is changed to 180
degrees to produce the flipping effect. When \c flipped is false, the
- item reverts to the default state, in which the \c angle value is 0.
-
+ item reverts to the default state, in which the \c angle value is 0.
+
\snippet doc/src/snippets/declarative/flipable/flipable.qml 0
\image flipable.gif
@@ -103,8 +103,8 @@ public:
its old and new values.
See \l {QML States} for details on state changes and the default
- state, and \l {QML Animation} for more information on how animations
- work within transitions.
+ state, and \l {QML Animation and Transitions} for more information on how
+ animations work within transitions.
\sa {declarative/ui-components/flipable}{Flipable example}
*/
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index af2b804..05e64b9 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -1267,7 +1267,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
\snippet doc/src/snippets/declarative/gridview/ContactModel.qml 0
- \div {float-right}
+ \div {class="float-right"}
\inlineimage gridview-simple.png
\enddiv
@@ -1283,7 +1283,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
\codeline
\snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs simple
- \div {float-right}
+ \div {class="float-right"}
\inlineimage gridview-highlight.png
\enddiv
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 4af91ce..6602dda 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -2747,7 +2747,7 @@ QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
}
\endqml
- \sa {qdeclarativeanimation.html#transitions}{QML Transitions}
+ \sa {QML Animation and Transitions}{Transitions}
*/
@@ -3455,7 +3455,7 @@ qreal QDeclarativeItem::implicitHeight() const
Setting the implicit size is useful for defining components that have a preferred size
based on their content, for example:
- \code
+ \qml
// Label.qml
import QtQuick 1.1
@@ -3472,7 +3472,7 @@ qreal QDeclarativeItem::implicitHeight() const
anchors.verticalCenter: parent.verticalCenter
}
}
- \endcode
+ \endqml
\bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
incurs a performance penalty as the text must be laid out twice.
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index 47d8f94..d4e7f7b 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -216,7 +216,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
\section1 Example Usage
- \div {float-right}
+ \div {class="float-right"}
\inlineimage qml-mousearea-snippet.png
\enddiv
@@ -315,7 +315,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
The \e accepted property of the MouseEvent parameter is ignored in this handler.
- \sa onCanceled()
+ \sa onCanceled
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
index 8f59073..b3235ef 100644
--- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
@@ -134,7 +134,7 @@ void QDeclarativeGradientStop::updateGradient()
\section1 Example Usage
- \div {float-right}
+ \div {class="float-right"}
\inlineimage qml-gradient.png
\enddiv
@@ -220,7 +220,7 @@ void QDeclarativeGradient::doUpdate()
\section1 Example Usage
- \div {float-right}
+ \div {class="float-right"}
\inlineimage declarative-rect.png
\enddiv
@@ -272,7 +272,7 @@ void QDeclarativeRectangle::doUpdate()
rectangle (as documented for QRect rendering). This can cause unintended effects if
\c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item:
- \div {float-right}
+ \div {class="float-right"}
\inlineimage rect-border-width.png
\enddiv
@@ -296,7 +296,7 @@ QDeclarativePen *QDeclarativeRectangle::border()
This property allows for the construction of simple vertical gradients.
Other gradients may by formed by adding rotation to the rectangle.
- \div {float-left}
+ \div {class="float-left"}
\inlineimage declarative-rect_gradient.png
\enddiv
@@ -364,7 +364,7 @@ void QDeclarativeRectangle::setRadius(qreal radius)
The default color is white.
- \div {float-right}
+ \div {class="float-right"}
\inlineimage rect-color.png
\enddiv
diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
index 31819f5..75d9f67 100644
--- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
@@ -299,7 +299,7 @@ void QDeclarativeTextLayout::clearLayout()
QTextLayout::clearLayout();
}
-void QDeclarativeTextLayout::prepare()
+void QDeclarativeTextLayout::prepare(QPainter *painter)
{
if (!d || !d->cached) {
@@ -308,6 +308,7 @@ void QDeclarativeTextLayout::prepare()
InertTextPainter *itp = inertTextPainter();
itp->device.begin(d);
+ itp->painter.setPen(painter->pen());
QTextLayout::draw(&itp->painter, QPointF(0, 0));
glyph_t *glyphPool = d->glyphs.data();
@@ -326,6 +327,12 @@ void QDeclarativeTextLayout::prepare()
}
}
+// Defined in qpainter.cpp
+extern Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat);
+
void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p)
{
QPainterPrivate *priv = QPainterPrivate::get(painter);
@@ -340,7 +347,7 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p)
return;
}
- prepare();
+ prepare(painter);
int itemCount = d->items.count();
@@ -371,6 +378,10 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p)
currentColor = item.color;
}
priv->extended->drawStaticTextItem(&item);
+
+ qt_draw_decoration_for_glyphs(painter, item.glyphs, item.glyphPositions,
+ item.numGlyphs, item.fontEngine(), painter->font(),
+ QTextCharFormat());
}
if (currentColor != oldPen.color())
painter->setPen(oldPen);
diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout_p.h b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h
index 2c9264e..23b22a6 100644
--- a/src/declarative/graphicsitems/qdeclarativetextlayout_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h
@@ -61,7 +61,7 @@ public:
void beginLayout();
void clearLayout();
- void prepare();
+ void prepare(QPainter *);
void draw(QPainter *, const QPointF & = QPointF());
private:
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index a8082f8..97ce059 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -839,7 +839,8 @@ void QDeclarativeVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
QML only operates on list data. \c rootIndex allows the children of
any node in a QAbstractItemModel to be provided by this model.
- This property only affects models of type QAbstractItemModel.
+ This property only affects models of type QAbstractItemModel that
+ are hierarchical (e.g, a tree model).
For example, here is a simple interactive file system browser.
When a directory name is clicked, the view's \c rootIndex is set to the
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index ac683a7..8238252 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -137,7 +137,7 @@ class QByteArray;
}
\endcode
- \sa {Using QML in C++ Applications}, {Integrating QML with existing Qt UI code}
+ \sa {Using QML Bindings in C++ Applications}, {Integrating QML Code with Existing Qt UI Code}
*/
/*!
@@ -643,11 +643,11 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
The \a properties argument is specified as a map of property-value items. For example, the code
below creates an object with initial \c x and \c y values of 100 and 200, respectively:
- \qml
+ \js
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready)
component.createObject(parent, {"x": 100, "y": 100});
- \endqml
+ \endjs
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic Object Management in QML} for more information.
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index dc6b085..7637b72 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -72,10 +72,10 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
Contexts allow data to be exposed to the QML components instantiated by the
QML engine.
- Each QDeclarativeContext contains a set of properties, distinct from its QObject
- properties, that allow data to be explicitly bound to a context by name. The
- context properties are defined and updated by calling
- QDeclarativeContext::setContextProperty(). The following example shows a Qt model
+ Each QDeclarativeContext contains a set of properties, distinct from its QObject
+ properties, that allow data to be explicitly bound to a context by name. The
+ context properties are defined and updated by calling
+ QDeclarativeContext::setContextProperty(). The following example shows a Qt model
being bound to a context and then accessed from a QML file.
\code
@@ -97,8 +97,8 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
To simplify binding and maintaining larger data sets, a context object can be set
on a QDeclarativeContext. All the properties of the context object are available
by name in the context, as though they were all individually added through calls
- to QDeclarativeContext::setContextProperty(). Changes to the property's values are
- detected through the property's notify signal. Setting a context object is both
+ to QDeclarativeContext::setContextProperty(). Changes to the property's values are
+ detected through the property's notify signal. Setting a context object is both
faster and easier than manually adding and maintaing context property values.
The following example has the same effect as the previous one, but it uses a context
@@ -121,7 +121,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
component.create(context);
\endcode
- All properties added explicitly by QDeclarativeContext::setContextProperty() take
+ All properties added explicitly by QDeclarativeContext::setContextProperty() take
precedence over the context object's properties.
\section2 The Context Hierarchy
@@ -147,8 +147,8 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
context2->setContextProperty("b", 15);
\endcode
- While QML objects instantiated in a context are not strictly owned by that
- context, their bindings are. If a context is destroyed, the property bindings of
+ While QML objects instantiated in a context are not strictly owned by that
+ context, their bindings are. If a context is destroyed, the property bindings of
outstanding QML objects will stop evaluating.
\warning Setting the context object or adding new context properties after an object
@@ -156,7 +156,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
to reevaluate). Thus whenever possible you should complete "setup" of the context
before using it to create any objects.
- \sa {Using QML in C++ Applications}
+ \sa {Using QML Bindings in C++ Applications}
*/
/*! \internal */
@@ -223,7 +223,7 @@ QDeclarativeContext::~QDeclarativeContext()
/*!
Returns whether the context is valid.
- To be valid, a context must have a engine, and it's contextObject(), if any,
+ To be valid, a context must have a engine, and it's contextObject(), if any,
must not have been deleted.
*/
bool QDeclarativeContext::isValid() const
@@ -384,7 +384,7 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
if (data->contextObject) {
QObject *obj = data->contextObject;
QDeclarativePropertyCache::Data local;
- QDeclarativePropertyCache::Data *property =
+ QDeclarativePropertyCache::Data *property =
QDeclarativePropertyCache::property(data->engine, obj, name, local);
if (property) value = obj->metaObject()->property(property->coreIndex).read(obj);
@@ -461,7 +461,7 @@ QUrl QDeclarativeContext::baseUrl() const
{
Q_D(const QDeclarativeContext);
const QDeclarativeContextData* data = d->data;
- while (data && data->url.isEmpty())
+ while (data && data->url.isEmpty())
data = data->parent;
if (data)
@@ -515,7 +515,7 @@ QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
void QDeclarativeContextData::invalidate()
{
- while (childContexts)
+ while (childContexts)
childContexts->invalidate();
while (componentAttached) {
@@ -570,7 +570,7 @@ void QDeclarativeContextData::clearContext()
void QDeclarativeContextData::destroy()
{
- if (linkedContext)
+ if (linkedContext)
linkedContext->destroy();
if (engine) invalidate();
@@ -626,9 +626,9 @@ void QDeclarativeContextData::setParent(QDeclarativeContextData *p)
}
}
-/*
-Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
-context-tree dependent caches in the expressions, and should occur every time the context tree
+/*
+Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
+context-tree dependent caches in the expressions, and should occur every time the context tree
*structure* (not values) changes.
*/
void QDeclarativeContextData::refreshExpressions()
@@ -656,7 +656,7 @@ void QDeclarativeContextData::addObject(QObject *o)
data->outerContext = this;
data->nextContextObject = contextObjects;
- if (data->nextContextObject)
+ if (data->nextContextObject)
data->nextContextObject->prevContextObject = &data->nextContextObject;
data->prevContextObject = &contextObjects;
contextObjects = data;
@@ -664,7 +664,7 @@ void QDeclarativeContextData::addObject(QObject *o)
void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script)
{
- if (!engine)
+ if (!engine)
return;
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
@@ -684,7 +684,7 @@ void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object
scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url));
scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());
-
+
QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
scriptContext->pushScope(scope);
@@ -752,7 +752,7 @@ QString QDeclarativeContextData::findObjectId(const QObject *obj) const
for (int i=0; i<idValueCount; i++) {
if (idValues[i] == obj)
return propertyNames->findId(i);
- }
+ }
if (linkedContext)
return linkedContext->findObjectId(obj);
@@ -761,7 +761,7 @@ QString QDeclarativeContextData::findObjectId(const QObject *obj) const
QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext()
{
- if (!publicContext)
+ if (!publicContext)
publicContext = new QDeclarativeContext(this);
return publicContext;
}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 854d910..824aeab 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -2117,7 +2117,7 @@ QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val
The newly added \a path will be first in the importPathList().
- \sa setImportPathList(), \l {QML Modules}
+ \sa setImportPathList(), {QML Modules}
*/
void QDeclarativeEngine::addImportPath(const QString& path)
{
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 36cdde9..26f3996 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -629,7 +629,18 @@ QDeclarativeTypeLoader::~QDeclarativeTypeLoader()
}
/*!
-Return a QDeclarativeTypeData for \a url. The QDeclarativeTypeData may be cached.
+\enum QDeclarativeTypeLoader::Option
+
+This enum defines the options that control the way type data is handled.
+
+\value None The default value, indicating that no other options
+ are enabled.
+\value PreserveParser The parser used to handle the type data is preserved
+ after the data has been parsed.
+*/
+
+/*!
+Returns a QDeclarativeTypeData for the specified \a url. The QDeclarativeTypeData may be cached.
*/
QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
{
@@ -650,8 +661,10 @@ QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
}
/*!
-Return a QDeclarativeTypeData for \a data with the provided base \a url. The
+Returns a QDeclarativeTypeData for the given \a data with the provided base \a url. The
QDeclarativeTypeData will not be cached.
+
+The specified \a options control how the loader handles type data.
*/
QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const QUrl &url, Options options)
{
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index 6938892..7f487a0 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -79,7 +79,7 @@ public:
Loading, // Prior to data being received and dataReceived() being called
WaitingForDependencies, // While there are outstanding addDependency()s
Complete, // Finished
- Error, // Error
+ Error // Error
};
enum Type {
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 67461b0..6a6dfe1 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
/*!
\qmlclass Animation QDeclarativeAbstractAnimation
- \ingroup qml-animation-transition
+ \ingroup qml-animation-transition
\since 4.7
\brief The Animation element is the base of all QML animations.
@@ -554,7 +554,7 @@ void QDeclarativeAbstractAnimation::timelineComplete()
/*!
\qmlclass PauseAnimation QDeclarativePauseAnimation
- \ingroup qml-animation-transition
+ \ingroup qml-animation-transition
\since 4.7
\inherits Animation
\brief The PauseAnimation element provides a pause for an animation.
@@ -571,7 +571,7 @@ void QDeclarativeAbstractAnimation::timelineComplete()
}
\endcode
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativePauseAnimation::QDeclarativePauseAnimation(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QDeclarativePauseAnimationPrivate), parent)
@@ -630,27 +630,27 @@ QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation()
\inherits PropertyAnimation
\brief The ColorAnimation element animates changes in color values.
- ColorAnimation is a specialized PropertyAnimation that defines an
+ ColorAnimation is a specialized PropertyAnimation that defines an
animation to be applied when a color value changes.
- Here is a ColorAnimation applied to the \c color property of a \l Rectangle
- as a property value source. It animates the \c color property's value from
+ Here is a ColorAnimation applied to the \c color property of a \l Rectangle
+ as a property value source. It animates the \c color property's value from
its current value to a value of "red", over 1000 milliseconds:
\snippet doc/src/snippets/declarative/coloranimation.qml 0
Like any other animation element, a ColorAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
-
- For convenience, when a ColorAnimation is used in a \l Transition, it will
- animate any \c color properties that have been modified during the state
- change. If a \l{PropertyAnimation::}{property} or
- \l{PropertyAnimation::}{properties} are explicitly set for the animation,
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
+
+ For convenience, when a ColorAnimation is used in a \l Transition, it will
+ animate any \c color properties that have been modified during the state
+ change. If a \l{PropertyAnimation::}{property} or
+ \l{PropertyAnimation::}{properties} are explicitly set for the animation,
then those are used instead.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeColorAnimation::QDeclarativeColorAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
@@ -686,10 +686,10 @@ QDeclarativeColorAnimation::~QDeclarativeColorAnimation()
If the ColorAnimation is defined within a \l Transition or \l Behavior,
this value defaults to the value defined in the starting state of the
- \l Transition, or the current value of the property at the moment the
+ \l Transition, or the current value of the property at the moment the
\l Behavior is triggered.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QColor QDeclarativeColorAnimation::from() const
{
@@ -712,7 +712,7 @@ void QDeclarativeColorAnimation::setFrom(const QColor &f)
\l Transition, or the value of the property change that triggered the
\l Behavior.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QColor QDeclarativeColorAnimation::to() const
{
@@ -868,7 +868,7 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
\inherits Animation
\brief The PropertyAction element allows immediate property changes during animation.
- PropertyAction is used to specify an immediate property change during an
+ PropertyAction is used to specify an immediate property change during an
animation. The property change is not animated.
It is useful for setting non-animated property values during an animation.
@@ -879,9 +879,9 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
\snippet doc/src/snippets/declarative/propertyaction.qml standalone
- PropertyAction is also useful for setting the exact point at which a property
- change should occur during a \l Transition. For example, if PropertyChanges
- was used in a \l State to rotate an item around a particular
+ PropertyAction is also useful for setting the exact point at which a property
+ change should occur during a \l Transition. For example, if PropertyChanges
+ was used in a \l State to rotate an item around a particular
\l {Item::}{transformOrigin}, it might be implemented like this:
\snippet doc/src/snippets/declarative/propertyaction.qml transition
@@ -893,13 +893,13 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
before the RotationAnimation begins:
\snippet doc/src/snippets/declarative/propertyaction-sequential.qml sequential
-
+
This immediately sets the \c transformOrigin property to the value defined
- in the end state of the \l Transition (i.e. the value defined in the
+ in the end state of the \l Transition (i.e. the value defined in the
PropertyAction object) so that the rotation animation begins with the
correct transform origin.
- \sa {QML Animation}, QtDeclarative
+ \sa {QML Animation and Transitions}, QtDeclarative
*/
QDeclarativePropertyAction::QDeclarativePropertyAction(QObject *parent)
: QDeclarativeAbstractAnimation(*(new QDeclarativePropertyActionPrivate), parent)
@@ -1129,25 +1129,25 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions,
\inherits PropertyAnimation
\brief The NumberAnimation element animates changes in qreal-type values.
- NumberAnimation is a specialized PropertyAnimation that defines an
+ NumberAnimation is a specialized PropertyAnimation that defines an
animation to be applied when a numerical value changes.
- Here is a NumberAnimation applied to the \c x property of a \l Rectangle
- as a property value source. It animates the \c x value from its current
+ Here is a NumberAnimation applied to the \c x property of a \l Rectangle
+ as a property value source. It animates the \c x value from its current
value to a value of 50, over 1000 milliseconds:
\snippet doc/src/snippets/declarative/numberanimation.qml 0
Like any other animation element, a NumberAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
Note that NumberAnimation may not animate smoothly if there are irregular
changes in the number value that it is tracking. If this is the case, use
SmoothedAnimation instead.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
@@ -1193,10 +1193,10 @@ void QDeclarativeNumberAnimation::init()
If the NumberAnimation is defined within a \l Transition or \l Behavior,
this value defaults to the value defined in the starting state of the
- \l Transition, or the current value of the property at the moment the
+ \l Transition, or the current value of the property at the moment the
\l Behavior is triggered.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
qreal QDeclarativeNumberAnimation::from() const
@@ -1219,7 +1219,7 @@ void QDeclarativeNumberAnimation::setFrom(qreal f)
\l Transition, or the value of the property change that triggered the
\l Behavior.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
qreal QDeclarativeNumberAnimation::to() const
{
@@ -1241,15 +1241,15 @@ void QDeclarativeNumberAnimation::setTo(qreal t)
\inherits PropertyAnimation
\brief The Vector3dAnimation element animates changes in QVector3d values.
- Vector3dAnimation is a specialized PropertyAnimation that defines an
+ Vector3dAnimation is a specialized PropertyAnimation that defines an
animation to be applied when a Vector3d value changes.
Like any other animation element, a Vector3dAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeVector3dAnimation::QDeclarativeVector3dAnimation(QObject *parent)
: QDeclarativePropertyAnimation(parent)
@@ -1270,10 +1270,10 @@ QDeclarativeVector3dAnimation::~QDeclarativeVector3dAnimation()
If the Vector3dAnimation is defined within a \l Transition or \l Behavior,
this value defaults to the value defined in the starting state of the
- \l Transition, or the current value of the property at the moment the
+ \l Transition, or the current value of the property at the moment the
\l Behavior is triggered.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QVector3D QDeclarativeVector3dAnimation::from() const
{
@@ -1295,7 +1295,7 @@ void QDeclarativeVector3dAnimation::setFrom(QVector3D f)
\l Transition, or the value of the property change that triggered the
\l Behavior.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QVector3D QDeclarativeVector3dAnimation::to() const
{
@@ -1318,7 +1318,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t)
\brief The RotationAnimation element animates changes in rotation values.
RotationAnimation is a specialized PropertyAnimation that gives control
- over the direction of rotation during an animation.
+ over the direction of rotation during an animation.
By default, it rotates in the direction
of the numerical change; a rotation from 0 to 240 will rotate 240 degrees
@@ -1334,7 +1334,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t)
Notice the RotationAnimation did not need to set a \l target
value. As a convenience, when used in a transition, RotationAnimation will rotate all
properties named "rotation" or "angle". You can override this by providing
- your own properties via \l {PropertyAnimation::properties}{properties} or
+ your own properties via \l {PropertyAnimation::properties}{properties} or
\l {PropertyAnimation::property}{property}.
Also, note the \l Rectangle will be rotated around its default
@@ -1344,11 +1344,11 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t)
PropertyAction documentation for more details.
Like any other animation element, a RotationAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress)
{
@@ -1421,10 +1421,10 @@ QDeclarativeRotationAnimation::~QDeclarativeRotationAnimation()
If the RotationAnimation is defined within a \l Transition or \l Behavior,
this value defaults to the value defined in the starting state of the
- \l Transition, or the current value of the property at the moment the
+ \l Transition, or the current value of the property at the moment the
\l Behavior is triggered.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
qreal QDeclarativeRotationAnimation::from() const
{
@@ -1446,7 +1446,7 @@ void QDeclarativeRotationAnimation::setFrom(qreal f)
\l Transition, or the value of the property change that triggered the
\l Behavior.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
qreal QDeclarativeRotationAnimation::to() const
{
@@ -1572,15 +1572,15 @@ QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGro
if this is the preferred behavior.
Like any other animation element, a SequentialAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \note Once an animation has been grouped into a SequentialAnimation or
+ \note Once an animation has been grouped into a SequentialAnimation or
ParallelAnimation, it cannot be individually started and stopped; the
SequentialAnimation or ParallelAnimation must be started and stopped as a group.
-
- \sa ParallelAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}
+
+ \sa ParallelAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent) :
@@ -1642,15 +1642,15 @@ void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actio
\snippet doc/src/snippets/declarative/parallelanimation.qml 0
Like any other animation element, a ParallelAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \note Once an animation has been grouped into a SequentialAnimation or
+ \note Once an animation has been grouped into a SequentialAnimation or
ParallelAnimation, it cannot be individually started and stopped; the
SequentialAnimation or ParallelAnimation must be started and stopped as a group.
- \sa SequentialAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa SequentialAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) :
QDeclarativeAnimationGroup(parent)
@@ -1745,14 +1745,14 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int
\inherits Animation
\brief The PropertyAnimation element animates changes in property values.
- PropertyAnimation provides a way to animate changes to a property's value.
+ PropertyAnimation provides a way to animate changes to a property's value.
It can be used to define animations in a number of ways:
-
+
\list
\o In a \l Transition
- For example, to animate any objects that have changed their \c x or \c y properties
+ For example, to animate any objects that have changed their \c x or \c y properties
as a result of a state change, using an \c InOutQuad easing curve:
\snippet doc/src/snippets/declarative/propertyanimation.qml transition
@@ -1792,12 +1792,12 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int
Depending on how the animation is used, the set of properties normally used will be
different. For more information see the individual property documentation, as well
- as the \l{QML Animation} introduction.
+ as the \l{QML Animation and Transitions} introduction.
Note that PropertyAnimation inherits the abstract \l Animation element.
This includes additional properties and methods for controlling the animation.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QObject *parent)
@@ -1857,10 +1857,10 @@ void QDeclarativePropertyAnimation::setDuration(int duration)
If the PropertyAnimation is defined within a \l Transition or \l Behavior,
this value defaults to the value defined in the starting state of the
- \l Transition, or the current value of the property at the moment the
+ \l Transition, or the current value of the property at the moment the
\l Behavior is triggered.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QVariant QDeclarativePropertyAnimation::from() const
{
@@ -1887,7 +1887,7 @@ void QDeclarativePropertyAnimation::setFrom(const QVariant &f)
\l Transition, or the value of the property change that triggered the
\l Behavior.
- \sa {QML Animation}
+ \sa {QML Animation and Transitions}
*/
QVariant QDeclarativePropertyAnimation::to() const
{
@@ -2254,7 +2254,7 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop)
As seen in the above example, properties is specified as a comma-separated string of property names to animate.
- \sa exclude, {QML Animation}
+ \sa exclude, {QML Animation and Transitions}
*/
QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::targets()
{
@@ -2437,7 +2437,7 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions
ParentAnimation is used to animate a parent change for an \l Item.
For example, the following ParentChange changes \c blueRect to become
- a child of \c redRect when it is clicked. The inclusion of the
+ a child of \c redRect when it is clicked. The inclusion of the
ParentAnimation, which defines a NumberAnimation to be applied during
the transition, ensures the item animates smoothly as it moves to
its new parent:
@@ -2452,17 +2452,17 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions
to animate the parent change via another item that does not have clipping
enabled. Such an item can be set using the \l via property.
- For convenience, when a ParentAnimation is used in a \l Transition, it will
- animate any ParentChange that has occurred during the state change.
+ For convenience, when a ParentAnimation is used in a \l Transition, it will
+ animate any ParentChange that has occurred during the state change.
This can be overridden by setting a specific target item using the
\l target property.
Like any other animation element, a ParentAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent)
: QDeclarativeAnimationGroup(*(new QDeclarativeParentAnimationPrivate), parent)
@@ -2795,23 +2795,23 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation()
\inherits Animation
\brief The AnchorAnimation element animates changes in anchor values.
- AnchorAnimation is used to animate an anchor change.
+ AnchorAnimation is used to animate an anchor change.
In the following snippet we animate the addition of a right anchor to a \l Rectangle:
\snippet doc/src/snippets/declarative/anchoranimation.qml 0
- For convenience, when an AnchorAnimation is used in a \l Transition, it will
- animate any AnchorChanges that have occurred during the state change.
+ For convenience, when an AnchorAnimation is used in a \l Transition, it will
+ animate any AnchorChanges that have occurred during the state change.
This can be overridden by setting a specific target item using the
\l target property.
Like any other animation element, an AnchorAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa {QML Animation}, AnchorChanges
+ \sa {QML Animation and Transitions}, AnchorChanges
*/
QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent)
diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp
index 84f929c..a1321e2 100644
--- a/src/declarative/util/qdeclarativebehavior.cpp
+++ b/src/declarative/util/qdeclarativebehavior.cpp
@@ -76,7 +76,7 @@ public:
\since 4.7
\brief The Behavior element allows you to specify a default animation for a property change.
- A Behavior defines the default animation to be applied whenever a
+ A Behavior defines the default animation to be applied whenever a
particular property value changes.
For example, the following Behavior defines a NumberAnimation to be run
@@ -94,7 +94,7 @@ public:
state change. For general advice on using Behaviors to animate state changes, see
\l{Using QML Behaviors with States}.
- \sa {QML Animation}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
+ \sa {QML Animation and Transitions}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
*/
@@ -206,7 +206,7 @@ void QDeclarativeBehavior::write(const QVariant &value)
d->animation->qtAnimation()->start();
d->blockRunningChanged = false;
if (!after.contains(d->property))
- QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
}
void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp
index 5a66aab..83a7d83 100644
--- a/src/declarative/util/qdeclarativeconnections.cpp
+++ b/src/declarative/util/qdeclarativeconnections.cpp
@@ -117,6 +117,8 @@ public:
id: area
}
// ...
+ \endqml
+ \qml
Connections {
target: area
onClicked: foo(parameters)
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 1d03842..258bc81 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -108,7 +108,7 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM
The following example shows a ListModel containing three elements, with the roles
"name" and "cost".
- \div {float-right}
+ \div {class="float-right"}
\inlineimage listmodel.png
\enddiv
@@ -133,7 +133,7 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM
The delegate displays all the fruit attributes:
- \div {float-right}
+ \div {class="float-right"}
\inlineimage listmodel-nested.png
\enddiv
@@ -143,7 +143,7 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM
\section1 Modifying List Models
The content of a ListModel may be created and modified using the clear(),
- append(), set() and setProperty() methods. For example:
+ append(), set(), insert() and setProperty() methods. For example:
\snippet doc/src/snippets/declarative/listmodel-modify.qml delegate
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 9221d78..a29854f 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -72,9 +72,7 @@ QT_BEGIN_NAMESPACE
// The cache limit describes the maximum "junk" in the cache.
// These are the same defaults as QPixmapCache
-#if defined(Q_OS_SYMBIAN)
-static int cache_limit = 1024 * 1024; // 1048 KB cache limit for symbian
-#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE)
+#if defined(Q_WS_QWS) || defined(Q_WS_WINCE)
static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded
#else
static int cache_limit = 10240 * 1024; // 10 MB cache limit for desktop
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 9bcb263..b03630d 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -118,12 +118,13 @@ QT_BEGIN_NAMESPACE
\section2 Immediate property changes in transitions
- When \l Transitions are used to animate state changes, they animate
- properties from their values in the current state to those defined in the
- new state (as defined by PropertyChanges objects). However,
- it is sometimes desirable to set a property value \e immediately during a
- \l Transition, without animation; in these cases, the PropertyAction
- element can be used to force an immediate property change.
+ When \l{QML Animation and Transitions}{Transitions} are used to animate
+ state changes, they animate properties from their values in the current
+ state to those defined in the new state (as defined by PropertyChanges
+ objects). However, it is sometimes desirable to set a property value
+ \e immediately during a \l Transition, without animation; in these cases,
+ the PropertyAction element can be used to force an immediate property
+ change.
See the PropertyAction documentation for more details.
diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp
index e2f6e3c..9def5b4 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation.cpp
+++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp
@@ -257,8 +257,8 @@ void QSmoothedAnimation::init()
A SmoothedAnimation animates a property's value to a set target value
using an ease in/out quad easing curve. When the target value changes,
- the easing curves used to animate between the old and new target values
- are smoothly spliced together to create a smooth movement to the new
+ the easing curves used to animate between the old and new target values
+ are smoothly spliced together to create a smooth movement to the new
target value that maintains the current velocity.
The follow example shows one \l Rectangle tracking the position of another
@@ -288,11 +288,11 @@ void QSmoothedAnimation::init()
of 0.5 will take 2000 ms to complete.
Like any other animation element, a SmoothedAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa SpringAnimation, NumberAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}
+ \sa SpringAnimation, NumberAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
*/
QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent)
diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
index 1212a1c..bb58b0a 100644
--- a/src/declarative/util/qdeclarativespringanimation.cpp
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -246,19 +246,19 @@ void QDeclarativeSpringAnimationPrivate::updateMode()
You can also limit the maximum \l velocity of the animation.
- The following \l Rectangle moves to the position of the mouse using a
+ The following \l Rectangle moves to the position of the mouse using a
SpringAnimation when the mouse is clicked. The use of the \l Behavior
- on the \c x and \c y values indicates that whenever these values are
+ on the \c x and \c y values indicates that whenever these values are
changed, a SpringAnimation should be applied.
\snippet doc/src/snippets/declarative/springanimation.qml 0
Like any other animation element, a SpringAnimation can be applied in a
- number of ways, including transitions, behaviors and property value
- sources. The \l {QML Animation} documentation shows a variety of methods
- for creating animations.
+ number of ways, including transitions, behaviors and property value
+ sources. The \l {QML Animation and Transitions} documentation shows a
+ variety of methods for creating animations.
- \sa SmoothedAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}, {declarative/toys/clocks}{Clocks example}
+ \sa SmoothedAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}, {declarative/toys/clocks}{Clocks example}
*/
QDeclarativeSpringAnimation::QDeclarativeSpringAnimation(QObject *parent)
@@ -299,7 +299,7 @@ void QDeclarativeSpringAnimation::setVelocity(qreal velocity)
This property describes how strongly the target is pulled towards the
source. The default value is 0 (that is, the spring-like motion is disabled).
-
+
The useful value range is 0 - 5.0.
When this property is set and the \l velocity value is greater than 0,
@@ -394,9 +394,9 @@ void QDeclarativeSpringAnimation::setModulus(qreal modulus)
\qmlproperty real SpringAnimation::mass
This property holds the "mass" of the property being moved.
- The value is 1.0 by default.
-
- A greater mass causes slower movement and a greater spring-like
+ The value is 1.0 by default.
+
+ A greater mass causes slower movement and a greater spring-like
motion when an item comes to rest.
*/
qreal QDeclarativeSpringAnimation::mass() const
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 5a4e2b1..5718e29 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -152,14 +152,14 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje
Notice the default state is referred to using an empty string ("").
- States are commonly used together with \l {Transitions} to provide
+ States are commonly used together with \l{QML Animation and Transitions}{Transitions} to provide
animations when state changes occur.
\note Setting the state of an object from within another state of the same object is
not allowed.
\sa {declarative/animation/states}{states example}, {qmlstates}{States},
- {qdeclarativeanimation.html#transitions}{QML Transitions}, QtDeclarative
+ {QML Animation and Transitions}{Transitions}, QtDeclarative
*/
QDeclarativeState::QDeclarativeState(QObject *parent)
: QObject(*(new QDeclarativeStatePrivate), parent)
diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp
index f1d0997..6459bf9 100644
--- a/src/declarative/util/qdeclarativestategroup.cpp
+++ b/src/declarative/util/qdeclarativestategroup.cpp
@@ -88,7 +88,7 @@ public:
/*!
\qmlclass StateGroup QDeclarativeStateGroup
- \ingroup qml-state-elements
+ \ingroup qml-state-elements
\since 4.7
\brief The StateGroup element provides state support for non-Item elements.
@@ -113,7 +113,7 @@ public:
}
\endqml
- \sa {qmlstate}{States} {Transitions}, {QtDeclarative}
+ \sa {qmlstate}{States} {QML Animation and Transitions}{Transitions}, {QtDeclarative}
*/
QDeclarativeStateGroup::QDeclarativeStateGroup(QObject *parent)
@@ -213,7 +213,7 @@ void QDeclarativeStateGroupPrivate::clear_states(QDeclarativeListProperty<QDecla
}
\endqml
- \sa {Transitions}
+ \sa {QML Animation and Transitions}{Transitions}
*/
QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeStateGroup::transitionsProperty()
{
diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp
index 063ec3e..1a574b8 100644
--- a/src/declarative/util/qdeclarativetransition.cpp
+++ b/src/declarative/util/qdeclarativetransition.cpp
@@ -60,24 +60,24 @@ QT_BEGIN_NAMESPACE
A Transition defines the animations to be applied when a \l State change occurs.
For example, the following \l Rectangle has two states: the default state, and
- an added "moved" state. In the "moved state, the rectangle's position changes
+ an added "moved" state. In the "moved state, the rectangle's position changes
to (50, 50). The added Transition specifies that when the rectangle
changes between the default and the "moved" state, any changes
to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad.
\snippet doc/src/snippets/declarative/transition.qml 0
- Notice the example does not require \l{PropertyAnimation::}{to} and
+ Notice the example does not require \l{PropertyAnimation::}{to} and
\l{PropertyAnimation::}{from} values for the NumberAnimation. As a convenience,
these properties are automatically set to the values of \c x and \c y before
and after the state change; the \c from values are provided by
the current values of \c x and \c y, and the \c to values are provided by
- the PropertyChanges object. If you wish, you can provide \l{PropertyAnimation::}{to} and
+ the PropertyChanges object. If you wish, you can provide \l{PropertyAnimation::}{to} and
\l{PropertyAnimation::}{from} values anyway to override the default values.
- By default, a Transition's animations are applied for any state change in the
- parent item. The Transition \l {Transition::}{from} and \l {Transition::}{to}
- values can be set to restrict the animations to only be applied when changing
+ By default, a Transition's animations are applied for any state change in the
+ parent item. The Transition \l {Transition::}{from} and \l {Transition::}{to}
+ values can be set to restrict the animations to only be applied when changing
from one particular state to another.
To define multiple transitions, specify \l Item::transitions as a list:
@@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
\l Behavior, the Transition animation overrides the \l Behavior for that
state change.
- \sa {QML Animation}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
+ \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
*/
//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
@@ -111,8 +111,8 @@ class QDeclarativeTransitionPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeTransition)
public:
- QDeclarativeTransitionPrivate()
- : fromState(QLatin1String("*")), toState(QLatin1String("*")),
+ QDeclarativeTransitionPrivate()
+ : fromState(QLatin1String("*")), toState(QLatin1String("*")),
reversed(false), reversible(false), endState(0)
{
group.trans = this;
@@ -249,7 +249,7 @@ void QDeclarativeTransition::setFromState(const QString &f)
is reversed, and it is not necessary to set this property to reverse
the transition.
- However, if a SequentialAnimation is used, or if the \l from or \l to
+ However, if a SequentialAnimation is used, or if the \l from or \l to
properties have been set, this property will need to be set to reverse
a transition when a state change is reverted. For example, the following
transition applies a sequential animation when the mouse is pressed,
@@ -257,7 +257,7 @@ void QDeclarativeTransition::setFromState(const QString &f)
\snippet doc/src/snippets/declarative/transition-reversible.qml 0
- If the transition did not set the \c to and \c reversible values, then
+ If the transition did not set the \c to and \c reversible values, then
on the mouse release, the transition would play the PropertyAnimation
before the ColorAnimation instead of reversing the sequence.
*/
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 13880c2..dcc078d 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -194,9 +194,9 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
\since 4.7
\brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface.
- QDeclarativeItem objects can be placed on a standard QGraphicsScene and
- displayed with QGraphicsView. QDeclarativeView is a QGraphicsView subclass
- provided as a convenience for displaying QML files, and connecting between
+ QDeclarativeItem objects can be placed on a standard QGraphicsScene and
+ displayed with QGraphicsView. QDeclarativeView is a QGraphicsView subclass
+ provided as a convenience for displaying QML files, and connecting between
QML and C++ Qt objects.
QDeclarativeView provides:
@@ -236,7 +236,7 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
If you're using your own QGraphicsScene-based scene with QDeclarativeView, remember to
enable scene's sticky focus mode and to set itemIndexMethod to QGraphicsScene::NoIndex.
- \sa {Integrating QML with existing Qt UI code}, {Using QML in C++ Applications}
+ \sa {Integrating QML Code with Existing Qt UI Code}, {Using QML Bindings in C++ Applications}
*/
@@ -250,7 +250,7 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
/*!
\fn QDeclarativeView::QDeclarativeView(QWidget *parent)
-
+
Constructs a QDeclarativeView with the given \a parent.
*/
QDeclarativeView::QDeclarativeView(QWidget *parent)
@@ -704,7 +704,7 @@ void QDeclarativeView::paintEvent(QPaintEvent *event)
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Painting);
int time = 0;
- if (frameRateDebug())
+ if (frameRateDebug())
time = d->frameTimer.restart();
#ifdef Q_WS_MAC
diff --git a/src/gui/dialogs/qabstractprintdialog.cpp b/src/gui/dialogs/qabstractprintdialog.cpp
index 3317018..ef46697 100644
--- a/src/gui/dialogs/qabstractprintdialog.cpp
+++ b/src/gui/dialogs/qabstractprintdialog.cpp
@@ -381,19 +381,11 @@ void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter)
If the dialog is accepted by the user, the QPrinter object is
correctly configured for printing.
- \raw HTML
- <table align="center">
- <tr><td>
- \endraw
- \inlineimage plastique-printdialog.png
- \raw HTML
- </td><td>
- \endraw
- \inlineimage plastique-printdialog-properties.png
- \raw HTML
- </td></tr>
- </table>
- \endraw
+ \table
+ \row
+ \o \inlineimage plastique-printdialog.png
+ \o \inlineimage plastique-printdialog-properties.png
+ \endtable
The printer dialog (shown above in Plastique style) enables access to common
printing properties. On X11 platforms that use the CUPS printing system, the
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index dd06445..8fd615a 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -1536,10 +1536,12 @@ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
/*!
\since 4.2
- Opens an information message box with the specified \a title and
- \a text. The standard \a buttons are added to the message box. \a
- defaultButton specifies the button used when \key Enter is
- pressed. \a defaultButton must refer to a button that was given in \a buttons.
+ Opens an information message box with the given \a title and
+ \a text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box.
+ \a defaultButton specifies the button used when \key Enter is pressed.
+ \a defaultButton must refer to a button that was given in \a buttons.
If \a defaultButton is QMessageBox::NoButton, QMessageBox
chooses a suitable default automatically.
@@ -1547,9 +1549,13 @@ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
\key Esc was pressed instead, the \l{Default and Escape Keys}
{escape button} is returned.
- The message box is an \l{Qt::ApplicationModal} {application modal}
+ The message box is an \l{Qt::ApplicationModal}{application modal}
dialog box.
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
\sa question(), warning(), critical()
*/
QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QString &title,
@@ -1564,8 +1570,10 @@ QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QStr
/*!
\since 4.2
- Opens a question message box with the specified \a title and \a
- text. The standard \a buttons are added to the message box. \a
+ Opens a question message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
defaultButton specifies the button used when \key Enter is
pressed. \a defaultButton must refer to a button that was given in \a buttons.
If \a defaultButton is QMessageBox::NoButton, QMessageBox
@@ -1578,6 +1586,10 @@ QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QStr
The message box is an \l{Qt::ApplicationModal} {application modal}
dialog box.
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
\sa information(), warning(), critical()
*/
QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString &title,
@@ -1590,8 +1602,10 @@ QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString
/*!
\since 4.2
- Opens a warning message box with the specified \a title and \a
- text. The standard \a buttons are added to the message box. \a
+ Opens a warning message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
defaultButton specifies the button used when \key Enter is
pressed. \a defaultButton must refer to a button that was given in \a buttons.
If \a defaultButton is QMessageBox::NoButton, QMessageBox
@@ -1604,6 +1618,10 @@ QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString
The message box is an \l{Qt::ApplicationModal} {application modal}
dialog box.
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
\sa question(), information(), critical()
*/
QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString &title,
@@ -1616,8 +1634,10 @@ QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString
/*!
\since 4.2
- Opens a critical message box with the specified \a title and \a
- text. The standard \a buttons are added to the message box. \a
+ Opens a critical message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
defaultButton specifies the button used when \key Enter is
pressed. \a defaultButton must refer to a button that was given in \a buttons.
If \a defaultButton is QMessageBox::NoButton, QMessageBox
@@ -1630,9 +1650,9 @@ QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString
The message box is an \l{Qt::ApplicationModal} {application modal}
dialog box.
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
\sa question(), warning(), information()
*/
diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp
index 6533d11..fabf9d1 100644
--- a/src/gui/egl/qegl_symbian.cpp
+++ b/src/gui/egl/qegl_symbian.cpp
@@ -42,6 +42,7 @@
#include <QtGui/qpaintdevice.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qwidget.h>
+#include <QtGui/private/qapplication_p.h>
#include "qegl_p.h"
#include "qeglcontext_p.h"
@@ -73,10 +74,14 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
return;
int devType = dev->devType();
- if (devType == QInternal::Image)
+ if (devType == QInternal::Image) {
setPixelFormat(static_cast<QImage *>(dev)->format());
- else
- setPixelFormat(QImage::Format_RGB32);
+ } else {
+ QImage::Format format = QImage::Format_RGB32;
+ if (QApplicationPrivate::instance() && QApplicationPrivate::instance()->useTranslucentEGLSurfaces)
+ format = QImage::Format_ARGB32_Premultiplied;
+ setPixelFormat(format);
+ }
}
diff --git a/src/gui/embedded/qvfbhdr.h b/src/gui/embedded/qvfbhdr.h
index 31704b3..84f82ac 100644
--- a/src/gui/embedded/qvfbhdr.h
+++ b/src/gui/embedded/qvfbhdr.h
@@ -53,36 +53,37 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
#ifndef QT_QWS_TEMP_DIR
-#define QT_QWS_TEMP_DIR "/tmp"
+# define QT_QWS_TEMP_DIR QLatin1String("/tmp")
#endif
#ifdef QT_PRIVATE_QWS
-#define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2-%3") \
- .arg(QT_QWS_TEMP_DIR).arg(getuid()).arg(DISPLAY)
-
+#define QT_VFB_DATADIR(DISPLAY) QString::fromLatin1("%1/qtembedded-%2-%3") \
+ .arg(QT_QWS_TEMP_DIR).arg(getuid()).arg(DISPLAY)
#define QT_VFB_MOUSE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/qtvfb_mouse")
+ .append(QLatin1String("/qtvfb_mouse"))
#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/qtvfb_keyboard")
+ .append(QLatin1String("/qtvfb_keyboard"))
#define QT_VFB_MAP(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/qtvfb_map")
+ .append(QLatin1String("/qtvfb_map"))
#define QT_VFB_SOUND_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/qt_soundserver")
+ .append(QLatin1String("/qt_soundserver"))
#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/QtEmbedded")
+ .append(QLatin1String("/QtEmbedded"))
#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY)
#else
-#define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QT_VFB_MOUSE_PIPE(DISPLAY) QString("/tmp/.qtvfb_mouse-%1").arg(DISPLAY)
-#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QString("/tmp/.qtvfb_keyboard-%1").arg(DISPLAY)
-#define QT_VFB_MAP(DISPLAY) QString("/tmp/.qtvfb_map-%1").arg(DISPLAY)
-#define QT_VFB_SOUND_PIPE(DISPLAY) QString("/tmp/.qt_soundserver-%1").arg(DISPLAY)
-#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append("/QtEmbedded-%1") \
- .arg(DISPLAY)
-#define QTE_PIPE_QVFB(DISPLAY) QString("/tmp/qtembedded-%1/QtEmbedded-%1") \
- .arg(DISPLAY)
+#define QT_VFB_DATADIR(DISPLAY) QString::fromLatin1("%1/qtembedded-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QT_VFB_MOUSE_PIPE(DISPLAY) QString::fromLatin1("%1/.qtvfb_mouse-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QString::fromLatin1("%1/.qtvfb_keyboard-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QT_VFB_MAP(DISPLAY) QString::fromLatin1("%1/.qtvfb_map-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QT_VFB_SOUND_PIPE(DISPLAY) QString::fromLatin1("%1/.qt_soundserver-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append(QLatin1String("/QtEmbedded-%1")).arg(DISPLAY)
+#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY)
#endif
struct QVFbHeader
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index 014b61b..9bb5424 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -56,7 +56,7 @@
Items that are anchored are automatically added to the layout, and if items
are removed, all their anchors will be automatically removed.
- \div {float-left}
+ \div {class="float-left"}
\inlineimage simpleanchorlayout-example.png Using an anchor layout to align simple colored widgets.
\enddiv
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index f463887..d51fdfe 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -417,6 +417,11 @@
click focus to items underneath when being clicked on. This flag
allows you create a non-focusable item that can be clicked on without
changing the focus. \endomit
+
+ \omitvalue ItemStopsFocusHandling \omit Same as
+ ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
+ allows you to completely take over focus handling.
+ This flag was introduced in Qt 4.7. \endomit
*/
/*!
@@ -574,19 +579,21 @@
QGraphicsItem pointer). The return value is unused; you cannot adjust
anything in this notification.
- \value ItemSceneChange The item is moved to a new scene. This notification
- is also sent when the item is added to its initial scene, and when it is
- removed. The value argument is the new scene (i.e., a QGraphicsScene
+ \value ItemSceneChange The item is moved to a new scene. This notification is
+ also sent when the item is added to its initial scene, and when it is removed.
+ The item's scene() is the old scene (or 0 if the item has not been added to a
+ scene yet). The value argument is the new scene (i.e., a QGraphicsScene
pointer), or a null pointer if the item is removed from a scene. Do not
- override this change by passing this item to QGraphicsScene::addItem() as
- this notification is delivered; instead, you can return the new scene from
+ override this change by passing this item to QGraphicsScene::addItem() as this
+ notification is delivered; instead, you can return the new scene from
itemChange(). Use this feature with caution; objecting to a scene change can
quickly lead to unwanted recursion.
- \value ItemSceneHasChanged The item's scene has changed. The value
- argument is the new scene (i.e., a pointer to a QGraphicsScene). Do not
- call setScene() in itemChange() as this notification is delivered. The
- return value is ignored.
+ \value ItemSceneHasChanged The item's scene has changed. The item's scene() is
+ the new scene. This notification is also sent when the item is added to its
+ initial scene, and when it is removed.The value argument is the new scene
+ (i.e., a pointer to a QGraphicsScene). Do not call setScene() in itemChange()
+ as this notification is delivered. The return value is ignored.
\value ItemCursorChange The item's cursor changes. The value argument is
the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
@@ -5577,8 +5584,10 @@ void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *s
parent->d_ptr->subFocusItemChange();
} while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
- if (scene && !scene->isActive())
+ if (scene && !scene->isActive()) {
+ scene->d_func()->passiveFocusItem = subFocusItem;
scene->d_func()->lastFocusItem = subFocusItem;
+ }
}
/*!
@@ -11549,6 +11558,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemStopsClickFocusPropagation:
str = "ItemStopsClickFocusPropagation";
break;
+ case QGraphicsItem::ItemStopsFocusHandling:
+ str = "ItemStopsFocusHandling";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index e59a7c9..67c9cd3 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -107,7 +107,8 @@ public:
ItemIsPanel = 0x4000,
ItemIsFocusScope = 0x8000, // internal
ItemSendsScenePositionChanges = 0x10000,
- ItemStopsClickFocusPropagation = 0x20000
+ ItemStopsClickFocusPropagation = 0x20000,
+ ItemStopsFocusHandling = 0x40000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 5c82116..90ff43f 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -559,7 +559,7 @@ public:
quint32 dirtyChildrenBoundingRect : 1;
// Packed 32 bits
- quint32 flags : 18;
+ quint32 flags : 19;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
quint32 geometryChanged : 1;
@@ -573,9 +573,9 @@ public:
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
quint32 notifyInvalidated : 1;
- quint32 mouseSetsFocus : 1;
// New 32 bits
+ quint32 mouseSetsFocus : 1;
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
quint32 holesInSiblingIndex : 1;
@@ -586,7 +586,7 @@ public:
quint32 mayHaveChildWithGraphicsEffect : 1;
quint32 isDeclarativeItem : 1;
quint32 sendParentChangeNotification : 1;
- quint32 padding : 22;
+ quint32 padding : 21;
// Optional stacking order
int globalStackingOrder;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index f997fc2..c0a4bf9 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -306,6 +306,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
rectAdjust(2),
focusItem(0),
lastFocusItem(0),
+ passiveFocusItem(0),
tabFocusFirst(0),
activePanel(0),
lastActivePanel(0),
@@ -630,6 +631,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
focusItem = 0;
if (item == lastFocusItem)
lastFocusItem = 0;
+ if (item == passiveFocusItem)
+ passiveFocusItem = 0;
if (item == activePanel) {
// ### deactivate...
activePanel = 0;
@@ -1317,8 +1320,10 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
+
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (item->isBlockedByModalPanel()) {
+ if (item->isBlockedByModalPanel()
+ || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
// Make sure we don't clear focus.
setFocus = true;
break;
@@ -1331,10 +1336,10 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
break;
}
}
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
- break;
if (item->isPanel())
break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
}
// Check for scene modality.
@@ -2980,7 +2985,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
QGraphicsItem *QGraphicsScene::focusItem() const
{
Q_D(const QGraphicsScene);
- return isActive() ? d->focusItem : d->lastFocusItem;
+ return isActive() ? d->focusItem : d->passiveFocusItem;
}
/*!
@@ -3054,6 +3059,7 @@ void QGraphicsScene::clearFocus()
Q_D(QGraphicsScene);
if (d->hasFocus) {
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, Qt::OtherFocusReason);
}
}
@@ -3756,9 +3762,9 @@ void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
focusEvent->ignore();
break;
default:
- if (d->lastFocusItem) {
+ if (d->passiveFocusItem) {
// Set focus on the last focus item
- setFocusItem(d->lastFocusItem, focusEvent->reason());
+ setFocusItem(d->passiveFocusItem, focusEvent->reason());
}
break;
}
@@ -3777,6 +3783,7 @@ void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
{
Q_D(QGraphicsScene);
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, focusEvent->reason());
// Remove all popups when the scene loses focus.
@@ -5925,6 +5932,7 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
+
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
@@ -5938,6 +5946,11 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
+ // Make sure we don't clear focus.
+ setFocus = true;
+ break;
+ }
}
// If nobody could take focus, clear it.
@@ -5970,8 +5983,6 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
}
if (item && item->isPanel())
break;
- if (item && (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation))
- break;
}
touchEvent->setAccepted(eventAccepted);
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 815c70b..2b47105 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -150,6 +150,7 @@ public:
quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
+ QGraphicsItem *passiveFocusItem;
QGraphicsWidget *tabFocusFirst;
QGraphicsItem *activePanel;
QGraphicsItem *lastActivePanel;
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 4d51fa8..cf492d6 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -55,11 +55,9 @@ DEFINES += Q_INTERNAL_QAPP_SRC
symbian {
TARGET.UID3=0x2001B2DD
- symbian-abld|symbian-sbsv2 {
- # ro-section in gui can exceed default allocated space, so move rw-section a little further
- QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
- QMAKE_LFLAGS.GCCE += -Tdata 0xC00000
- }
+ # ro-section in gui can exceed default allocated space, so move rw-section a little further
+ QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
+ QMAKE_LFLAGS.GCCE += -Tdata 0x800000
}
neon:*-g++* {
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index f89706c..00dccbe 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -28,7 +28,10 @@ HEADERS += \
image/qpixmapdata_p.h \
image/qpixmapdatafactory_p.h \
image/qpixmapfilter_p.h \
- image/qimagepixmapcleanuphooks_p.h
+ image/qimagepixmapcleanuphooks_p.h \
+ image/qvolatileimage_p.h \
+ image/qvolatileimagedata_p.h \
+ image/qnativeimagehandleprovider_p.h
SOURCES += \
image/qbitmap.cpp \
@@ -51,7 +54,8 @@ SOURCES += \
image/qmovie.cpp \
image/qpixmap_raster.cpp \
image/qnativeimage.cpp \
- image/qimagepixmapcleanuphooks.cpp
+ image/qimagepixmapcleanuphooks.cpp \
+ image/qvolatileimage.cpp
win32 {
SOURCES += image/qpixmap_win.cpp
@@ -72,6 +76,13 @@ else:symbian {
SOURCES += image/qpixmap_s60.cpp
}
+!symbian|contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2) {
+ SOURCES += image/qvolatileimagedata.cpp
+}
+else {
+ SOURCES += image/qvolatileimagedata_symbian.cpp
+}
+
# Built-in image format support
HEADERS += \
image/qbmphandler_p.h \
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index d0cc937..59c384a 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -964,12 +964,15 @@ QString QIcon::themeName()
Returns the QIcon corresponding to \a name in the current
icon theme. If no such icon is found in the current theme
- \a fallback is return instead.
+ \a fallback is returned instead.
- The lastest version of the freedesktop icon specification and naming
- spesification can be obtained here:
- http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
- http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
+ The latest version of the freedesktop icon specification and naming
+ specification can be obtained here:
+
+ \list
+ \o \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}
+ \o \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}
+ \endlist
To fetch an icon from the current icon theme:
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 168c518..441bdb1 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -833,6 +833,8 @@ QImage::QImage()
Constructs an image with the given \a width, \a height and \a
format.
+ A \l{isNull()}{null} image will be returned if memory cannot be allocated.
+
\warning This will create a QImage with uninitialized data. Call
fill() to fill the image with an appropriate pixel value before
drawing onto it with QPainter.
@@ -846,6 +848,8 @@ QImage::QImage(int width, int height, Format format)
/*!
Constructs an image with the given \a size and \a format.
+ A \l{isNull()}{null} image is returned if memory cannot be allocated.
+
\warning This will create a QImage with uninitialized data. Call
fill() to fill the image with an appropriate pixel value before
drawing onto it with QPainter.
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 1fa1058..e7b1000 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1482,6 +1482,9 @@ QByteArray QImageReader::imageFormat(QIODevice *device)
configure script or check the appropriate option in the graphical
installer.
+ Note that the QApplication instance must be created before this function is
+ called.
+
\sa setFormat(), QImageWriter::supportedImageFormats(), QImageIOPlugin
*/
QList<QByteArray> QImageReader::supportedImageFormats()
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 8a65ac0..504260a 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -679,6 +679,9 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
Reading and writing SVG files is supported through Qt's
\l{QtSvg Module}{SVG Module}.
+ Note that the QApplication instance must be created before this function is
+ called.
+
\sa setFormat(), QImageReader::supportedImageFormats(), QImageIOPlugin
*/
QList<QByteArray> QImageWriter::supportedImageFormats()
diff --git a/src/gui/image/qnativeimagehandleprovider_p.h b/src/gui/image/qnativeimagehandleprovider_p.h
new file mode 100644
index 0000000..4e6ed38
--- /dev/null
+++ b/src/gui/image/qnativeimagehandleprovider_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNATIVEIMAGEHANDLEPROVIDER_P_H
+#define QNATIVEIMAGEHANDLEPROVIDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNativeImageHandleProvider
+{
+public:
+ virtual void get(void **handle, QString *type) = 0;
+ virtual void release(void *handle, const QString &type) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QNATIVEIMAGEHANDLEPROVIDER_P_H
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 0aefafb..1a83318 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1997,7 +1997,7 @@ void QPixmap::detach()
}
if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapDataModificationHooks(pd);
+ QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data());
#if defined(Q_WS_MAC)
QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 368600f..5e0ffa8 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -380,6 +380,9 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace)
{
QImage::Format format;
+ if (flags & Qt::NoFormatConversion)
+ format = sourceImage.format();
+ else
#ifdef Q_WS_QWS
if (pixelType() == BitmapType) {
format = QImage::Format_Mono;
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index ca5f133..32d8dd7 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -374,6 +374,8 @@ CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
To be sure that QPixmap does not modify your original instance, you should
make a copy of your \c CFbsBitmap before calling this function.
If the CFbsBitmap is not valid this function will return a null QPixmap.
+ For performance reasons it is recommended to use a \a bitmap with a display
+ mode of EColor16MAP or EColor16MU whenever possible.
\warning This function is only available on Symbian OS.
@@ -599,6 +601,9 @@ bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
return res;
}
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
+
int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
if (!cfbsBitmap)
@@ -609,28 +614,18 @@ int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
return cfbsBitmap->SizeInPixels().iWidth;
case QPaintDevice::PdmHeight:
return cfbsBitmap->SizeInPixels().iHeight;
- case QPaintDevice::PdmWidthMM: {
- TInt twips = cfbsBitmap->SizeInTwips().iWidth;
- return (int)(twips * (25.4/KTwipsPerInch));
- }
- case QPaintDevice::PdmHeightMM: {
- TInt twips = cfbsBitmap->SizeInTwips().iHeight;
- return (int)(twips * (25.4/KTwipsPerInch));
- }
+ case QPaintDevice::PdmWidthMM:
+ return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX());
+ case QPaintDevice::PdmHeightMM:
+ return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY());
case QPaintDevice::PdmNumColors:
return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode());
case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX: {
- TReal inches = cfbsBitmap->SizeInTwips().iWidth / (TReal)KTwipsPerInch;
- TInt pixels = cfbsBitmap->SizeInPixels().iWidth;
- return pixels / inches;
- }
+ case QPaintDevice::PdmPhysicalDpiX:
+ return qt_defaultDpiX();
case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY: {
- TReal inches = cfbsBitmap->SizeInTwips().iHeight / (TReal)KTwipsPerInch;
- TInt pixels = cfbsBitmap->SizeInPixels().iHeight;
- return pixels / inches;
- }
+ case QPaintDevice::PdmPhysicalDpiY:
+ return qt_defaultDpiY();
case QPaintDevice::PdmDepth:
return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode());
default:
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 41fc6e9..ae772d8 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -91,9 +91,7 @@ QT_BEGIN_NAMESPACE
\sa QCache, QPixmap
*/
-#if defined(Q_OS_SYMBIAN)
-static int cache_limit = 1024; // 1048 KB cache limit for symbian
-#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE)
+#if defined(Q_WS_QWS) || defined(Q_WS_WINCE)
static int cache_limit = 2048; // 2048 KB cache limit for embedded
#else
static int cache_limit = 10240; // 10 MB cache limit for desktop
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 7699344..0d0d417 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -71,7 +71,9 @@ public:
#if defined(Q_OS_SYMBIAN)
enum NativeType {
FbsBitmap,
- SgImage
+ SgImage,
+ VolatileImage,
+ NativeImageHandleProvider
};
#endif
enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass,
diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp
new file mode 100644
index 0000000..098e9a1
--- /dev/null
+++ b/src/gui/image/qvolatileimage.cpp
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvolatileimage_p.h"
+#include "qvolatileimagedata_p.h"
+#include <QtGui/private/qpaintengine_raster_p.h>
+#include <QtGui/private/qpixmapdata_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImagePaintEnginePrivate : public QRasterPaintEnginePrivate
+{
+public:
+ QVolatileImagePaintEnginePrivate() { }
+ QVolatileImage *img;
+};
+
+class QVolatileImagePaintEngine : public QRasterPaintEngine
+{
+ Q_DECLARE_PRIVATE(QVolatileImagePaintEngine)
+
+public:
+ QVolatileImagePaintEngine(QPaintDevice *device, QVolatileImage *img);
+ bool begin(QPaintDevice *device);
+ bool end();
+ void drawPixmap(const QPointF &p, const QPixmap &pm);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+};
+
+QVolatileImage::QVolatileImage()
+ : d(new QVolatileImageData)
+{
+}
+
+QVolatileImage::QVolatileImage(int w, int h, QImage::Format format)
+ : d(new QVolatileImageData(w, h, format))
+{
+}
+
+QVolatileImage::QVolatileImage(const QImage &sourceImage)
+ : d(new QVolatileImageData(sourceImage))
+{
+}
+
+QVolatileImage::QVolatileImage(void *nativeImage, void *nativeMask)
+ : d(new QVolatileImageData(nativeImage, nativeMask))
+{
+}
+
+// Need non-inline, non-autogenerated copy ctor, dtor, op= to keep the
+// fwd declared QSharedData working.
+
+QVolatileImage::QVolatileImage(const QVolatileImage &other)
+ : d(other.d)
+{
+}
+
+QVolatileImage::~QVolatileImage()
+{
+}
+
+QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs)
+{
+ d = rhs.d;
+ return *this;
+}
+
+bool QVolatileImage::isNull() const
+{
+ return d->image.isNull();
+}
+
+QImage::Format QVolatileImage::format() const
+{
+ return d->image.format();
+}
+
+int QVolatileImage::width() const
+{
+ return d->image.width();
+}
+
+int QVolatileImage::height() const
+{
+ return d->image.height();
+}
+
+int QVolatileImage::bytesPerLine() const
+{
+ return d->image.bytesPerLine();
+}
+
+int QVolatileImage::byteCount() const
+{
+ return d->image.byteCount();
+}
+
+int QVolatileImage::depth() const
+{
+ return d->image.depth();
+}
+
+bool QVolatileImage::hasAlphaChannel() const
+{
+ return d->image.hasAlphaChannel();
+}
+
+void QVolatileImage::beginDataAccess() const
+{
+ d->beginDataAccess();
+}
+
+void QVolatileImage::endDataAccess(bool readOnly) const
+{
+ d->endDataAccess(readOnly);
+}
+
+/*!
+ Access to pixel data via bits() or constBits() should be guarded by
+ begin/endDataAccess().
+ */
+uchar *QVolatileImage::bits()
+{
+ return d->image.bits();
+}
+
+const uchar *QVolatileImage::constBits() const
+{
+ return d->image.constBits();
+}
+
+bool QVolatileImage::ensureFormat(QImage::Format format)
+{
+ return d->ensureFormat(format);
+}
+
+/*!
+ This will always perform a copy of the pixel data.
+ */
+QImage QVolatileImage::toImage() const
+{
+ d->beginDataAccess();
+ QImage newImage = d->image.copy(); // no sharing allowed
+ d->endDataAccess(true);
+ return newImage;
+}
+
+/*!
+ Returns a reference to the image that is potentially using some native
+ buffer internally. Access to the image's pixel data should be guarded by
+ begin/endDataAccess(). Use it when there is a need for QImage APIs not provided
+ by this class. The returned QImage must never be shared or assigned to.
+ */
+QImage &QVolatileImage::imageRef() // non-const, in order to cause a detach
+{
+ d->ensureImage();
+ return d->image;
+}
+
+void *QVolatileImage::duplicateNativeImage() const
+{
+ return d->duplicateNativeImage();
+}
+
+void QVolatileImage::setAlphaChannel(const QPixmap &alphaChannel)
+{
+ ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ beginDataAccess();
+ imageRef().setAlphaChannel(alphaChannel.toImage());
+ endDataAccess();
+ d->ensureImage();
+}
+
+void QVolatileImage::fill(uint pixelValue)
+{
+ beginDataAccess();
+ imageRef().fill(pixelValue);
+ endDataAccess();
+ d->ensureImage();
+}
+
+void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect)
+{
+ if (source->isNull()) {
+ return;
+ }
+ QRect r = rect;
+ if (rect.isNull()) {
+ r = QRect(0, 0, source->width(), source->height());
+ }
+ source->beginDataAccess();
+ QImage &srcImgRef(source->imageRef());
+ int srcbpl = srcImgRef.bytesPerLine();
+ int srcbpp = srcImgRef.depth() / 8;
+ const uchar *sptr = srcImgRef.constBits() + r.y() * srcbpl;
+ beginDataAccess();
+ QImage &dstImgRef(imageRef());
+ int dstbpl = dstImgRef.bytesPerLine();
+ uchar *dptr = dstImgRef.bits();
+ for (int y = 0; y < r.height(); ++y) {
+ qMemCopy(dptr, sptr + r.x() * srcbpp, r.width() * srcbpp);
+ sptr += srcbpl;
+ dptr += dstbpl;
+ }
+ endDataAccess();
+ source->endDataAccess(true);
+}
+
+/*!
+ To be called from the PixmapData's paintEngine().
+ */
+QPaintEngine *QVolatileImage::paintEngine()
+{
+ if (!d->pengine) {
+ d->pengine = new QVolatileImagePaintEngine(&imageRef(), this);
+ }
+ return d->pengine;
+}
+
+QVolatileImagePaintEngine::QVolatileImagePaintEngine(QPaintDevice *device,
+ QVolatileImage *img)
+ : QRasterPaintEngine(*(new QVolatileImagePaintEnginePrivate), device)
+{
+ Q_D(QVolatileImagePaintEngine);
+ d->img = img;
+}
+
+bool QVolatileImagePaintEngine::begin(QPaintDevice *device)
+{
+ Q_D(QVolatileImagePaintEngine);
+ d->img->beginDataAccess();
+ return QRasterPaintEngine::begin(device);
+}
+
+bool QVolatileImagePaintEngine::end()
+{
+ Q_D(QVolatileImagePaintEngine);
+ bool ret = QRasterPaintEngine::end();
+ d->img->endDataAccess();
+ return ret;
+}
+
+// For non-RasterClass pixmaps drawPixmap() would call toImage() which is slow in
+// our case. Therefore drawPixmap() is rerouted to drawImage().
+
+void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
+{
+#ifdef Q_OS_SYMBIAN
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(p, img->imageRef());
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(p, pm);
+ }
+#else
+ QRasterPaintEngine::drawPixmap(p, pm);
+#endif
+}
+
+void QVolatileImagePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+#ifdef Q_OS_SYMBIAN
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ }
+#else
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h
new file mode 100644
index 0000000..fc5d6b1
--- /dev/null
+++ b/src/gui/image/qvolatileimage_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVOLATILEIMAGE_P_H
+#define QVOLATILEIMAGE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qimage.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImageData;
+
+class Q_GUI_EXPORT QVolatileImage
+{
+public:
+ QVolatileImage();
+ QVolatileImage(int w, int h, QImage::Format format);
+ explicit QVolatileImage(const QImage &sourceImage);
+ explicit QVolatileImage(void *nativeImage, void *nativeMask = 0);
+ QVolatileImage(const QVolatileImage &other);
+ ~QVolatileImage();
+ QVolatileImage &operator=(const QVolatileImage &rhs);
+
+ bool isNull() const;
+ QImage::Format format() const;
+ int width() const;
+ int height() const;
+ int bytesPerLine() const;
+ int byteCount() const;
+ int depth() const;
+ bool hasAlphaChannel() const;
+ void beginDataAccess() const;
+ void endDataAccess(bool readOnly = false) const;
+ uchar *bits();
+ const uchar *constBits() const;
+ bool ensureFormat(QImage::Format format);
+ QImage toImage() const;
+ QImage &imageRef();
+ QPaintEngine *paintEngine();
+ void setAlphaChannel(const QPixmap &alphaChannel);
+ void fill(uint pixelValue);
+ void *duplicateNativeImage() const;
+ void copyFrom(QVolatileImage *source, const QRect &rect);
+
+private:
+ QSharedDataPointer<QVolatileImageData> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QVOLATILEIMAGE_P_H
diff --git a/src/gui/image/qvolatileimagedata.cpp b/src/gui/image/qvolatileimagedata.cpp
new file mode 100644
index 0000000..51b5995
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvolatileimagedata_p.h"
+#include <QtGui/qpaintengine.h>
+
+QT_BEGIN_NAMESPACE
+
+QVolatileImageData::QVolatileImageData()
+ : pengine(0)
+{
+}
+
+QVolatileImageData::QVolatileImageData(int w, int h, QImage::Format format)
+ : pengine(0)
+{
+ image = QImage(w, h, format);
+}
+
+QVolatileImageData::QVolatileImageData(const QImage &sourceImage)
+ : pengine(0)
+{
+ image = sourceImage;
+}
+
+QVolatileImageData::QVolatileImageData(void *, void *)
+ : pengine(0)
+{
+ // Not supported.
+}
+
+QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
+{
+ image = other.image;
+ // The detach is not mandatory here but we do it nonetheless in order to
+ // keep the behavior consistent with other platforms.
+ image.detach();
+ pengine = 0;
+}
+
+QVolatileImageData::~QVolatileImageData()
+{
+ delete pengine;
+}
+
+void QVolatileImageData::beginDataAccess() const
+{
+ // nothing to do here
+}
+
+void QVolatileImageData::endDataAccess(bool readOnly) const
+{
+ Q_UNUSED(readOnly);
+ // nothing to do here
+}
+
+bool QVolatileImageData::ensureFormat(QImage::Format format)
+{
+ if (image.format() != format) {
+ image = image.convertToFormat(format);
+ }
+ return true;
+}
+
+void *QVolatileImageData::duplicateNativeImage() const
+{
+ return 0;
+}
+
+void QVolatileImageData::ensureImage()
+{
+ // nothing to do here
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qvolatileimagedata_p.h b/src/gui/image/qvolatileimagedata_p.h
new file mode 100644
index 0000000..dab1685
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVOLATILEIMAGEDATA_P_H
+#define QVOLATILEIMAGEDATA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qimage.h>
+#include <QtCore/qshareddata.h>
+
+#ifdef Q_OS_SYMBIAN
+class CFbsBitmap;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QVolatileImageData : public QSharedData
+{
+public:
+ QVolatileImageData();
+ QVolatileImageData(int w, int h, QImage::Format format);
+ QVolatileImageData(const QImage &sourceImage);
+ QVolatileImageData(void *nativeImage, void *nativeMask);
+ QVolatileImageData(const QVolatileImageData &other);
+ ~QVolatileImageData();
+
+ void beginDataAccess() const;
+ void endDataAccess(bool readOnly = false) const;
+ bool ensureFormat(QImage::Format format);
+ void *duplicateNativeImage() const;
+ void ensureImage();
+
+#ifdef Q_OS_SYMBIAN
+ void updateImage();
+ void initWithBitmap(CFbsBitmap *source);
+ void applyMask(CFbsBitmap *mask);
+ void ensureBitmap();
+ void release();
+ QVolatileImageData *next;
+ QVolatileImageData *prev;
+ CFbsBitmap *bitmap;
+#endif
+ QImage image;
+ QPaintEngine *pengine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QVOLATILEIMAGEDATA_P_H
diff --git a/src/gui/image/qvolatileimagedata_symbian.cpp b/src/gui/image/qvolatileimagedata_symbian.cpp
new file mode 100644
index 0000000..6e2909b
--- /dev/null
+++ b/src/gui/image/qvolatileimagedata_symbian.cpp
@@ -0,0 +1,474 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvolatileimagedata_p.h"
+#include <fbs.h>
+#include <QtGui/private/qt_s60_p.h>
+#include <QtGui/qpaintengine.h>
+#include <QtGui/private/qimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static CFbsBitmap *rasterizeBitmap(CFbsBitmap *bitmap, TDisplayMode newMode)
+{
+ if (!bitmap) {
+ return 0;
+ }
+ QScopedPointer<CFbsBitmap> newBitmap(new CFbsBitmap);
+ if (newBitmap->Create(bitmap->SizeInPixels(), newMode) != KErrNone) {
+ qWarning("QVolatileImage: Failed to create new bitmap");
+ return 0;
+ }
+ CFbsBitmapDevice *bitmapDevice = 0;
+ CFbsBitGc *bitmapGc = 0;
+ QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(newBitmap.data()));
+ QScopedPointer<CFbsBitmapDevice> bitmapDevicePtr(bitmapDevice);
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
+ bitmapGc->BitBlt(TPoint(), bitmap);
+ delete bitmapGc;
+ return newBitmap.take();
+}
+
+static inline TDisplayMode format2TDisplayMode(QImage::Format format)
+{
+ TDisplayMode mode;
+ switch (format) {
+ case QImage::Format_MonoLSB:
+ mode = EGray2;
+ break;
+ case QImage::Format_Indexed8:
+ mode = EColor256;
+ break;
+ case QImage::Format_RGB444:
+ mode = EColor4K;
+ break;
+ case QImage::Format_RGB16:
+ mode = EColor64K;
+ break;
+ case QImage::Format_RGB888:
+ mode = EColor16M;
+ break;
+ case QImage::Format_RGB32:
+ mode = EColor16MU;
+ break;
+ case QImage::Format_ARGB32:
+ mode = EColor16MA;
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ mode = Q_SYMBIAN_ECOLOR16MAP;
+ break;
+ default:
+ mode = ENone;
+ break;
+ }
+ return mode;
+}
+
+static CFbsBitmap *imageToBitmap(const QImage &image)
+{
+ if (image.isNull()) {
+ return 0;
+ }
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Create(TSize(image.width(), image.height()),
+ format2TDisplayMode(image.format())) == KErrNone) {
+ bitmap->BeginDataAccess();
+ uchar *dptr = reinterpret_cast<uchar *>(bitmap->DataAddress());
+ int bmpLineLen = bitmap->DataStride();
+ int imgLineLen = image.bytesPerLine();
+ if (bmpLineLen == imgLineLen) {
+ qMemCopy(dptr, image.constBits(), image.byteCount());
+ } else {
+ int len = qMin(bmpLineLen, imgLineLen);
+ const uchar *sptr = image.constBits();
+ for (int y = 0; y < image.height(); ++y) {
+ qMemCopy(dptr, sptr, len);
+ dptr += bmpLineLen;
+ sptr += imgLineLen;
+ }
+ }
+ bitmap->EndDataAccess();
+ } else {
+ qWarning("QVolatileImage: Failed to create source bitmap");
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static CFbsBitmap *copyData(const QVolatileImageData &source)
+{
+ source.beginDataAccess();
+ CFbsBitmap *bmp = imageToBitmap(source.image);
+ source.endDataAccess();
+ return bmp;
+}
+
+static CFbsBitmap *convertData(const QVolatileImageData &source, QImage::Format newFormat)
+{
+ source.beginDataAccess();
+ QImage img = source.image.convertToFormat(newFormat);
+ CFbsBitmap *bmp = imageToBitmap(img);
+ source.endDataAccess();
+ return bmp;
+}
+
+static CFbsBitmap *duplicateBitmap(const CFbsBitmap &sourceBitmap)
+{
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Duplicate(sourceBitmap.Handle()) != KErrNone) {
+ qWarning("QVolatileImage: Failed to duplicate source bitmap");
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static CFbsBitmap *createBitmap(int w, int h, QImage::Format format)
+{
+ CFbsBitmap *bitmap = new CFbsBitmap;
+ if (bitmap->Create(TSize(w, h), format2TDisplayMode(format)) != KErrNone) {
+ qWarning("QVolatileImage: Failed to create source bitmap %d,%d (%d)", w, h, format);
+ delete bitmap;
+ bitmap = 0;
+ }
+ return bitmap;
+}
+
+static inline bool bitmapNeedsCopy(CFbsBitmap *bitmap)
+{
+ bool needsCopy = bitmap->IsCompressedInRAM();
+#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+ needsCopy |= (bitmap->ExtendedBitmapType() != KNullUid);
+#endif
+ return needsCopy;
+}
+
+static bool cleanup_function_registered = false;
+static QVolatileImageData *firstImageData = 0;
+
+static void cleanup()
+{
+ if (RFbsSession::GetSession()) {
+ QVolatileImageData *imageData = firstImageData;
+ while (imageData) {
+ imageData->release();
+ imageData = imageData->next;
+ }
+ }
+}
+
+static void ensureCleanup()
+{
+ // Destroy all underlying bitmaps in a post routine to prevent panics.
+ // This is a must because CFbsBitmap destructor needs the fbs session,
+ // that was used to create the bitmap, to be open still.
+ if (!cleanup_function_registered) {
+ qAddPostRoutine(cleanup);
+ cleanup_function_registered = true;
+ }
+}
+
+static void registerImageData(QVolatileImageData *imageData)
+{
+ ensureCleanup();
+ imageData->next = firstImageData;
+ if (firstImageData) {
+ firstImageData->prev = imageData;
+ }
+ firstImageData = imageData;
+}
+
+static void unregisterImageData(QVolatileImageData *imageData)
+{
+ if (imageData->prev) {
+ imageData->prev->next = imageData->next;
+ } else {
+ firstImageData = imageData->next;
+ }
+ if (imageData->next) {
+ imageData->next->prev = imageData->prev;
+ }
+}
+
+QVolatileImageData::QVolatileImageData()
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+}
+
+QVolatileImageData::QVolatileImageData(int w, int h, QImage::Format format)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ bitmap = createBitmap(w, h, format);
+ updateImage();
+}
+
+QVolatileImageData::QVolatileImageData(const QImage &sourceImage)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ image = sourceImage;
+ // The following is not mandatory, but we do it here to have a bitmap
+ // created always in order to reduce local heap usage.
+ ensureBitmap();
+}
+
+QVolatileImageData::QVolatileImageData(void *nativeImage, void *nativeMask)
+ : next(0), prev(0), bitmap(0), pengine(0)
+{
+ registerImageData(this);
+ if (nativeImage) {
+ CFbsBitmap *source = static_cast<CFbsBitmap *>(nativeImage);
+ CFbsBitmap *mask = static_cast<CFbsBitmap *>(nativeMask);
+ initWithBitmap(source);
+ if (mask) {
+ applyMask(mask);
+ }
+ }
+}
+
+QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
+{
+ bitmap = 0;
+ pengine = 0;
+ next = prev = 0;
+ registerImageData(this);
+ if (!other.image.isNull()) {
+ bitmap = copyData(other);
+ updateImage();
+ }
+}
+
+QVolatileImageData::~QVolatileImageData()
+{
+ release();
+ unregisterImageData(this);
+}
+
+void QVolatileImageData::release()
+{
+ delete bitmap;
+ bitmap = 0;
+ delete pengine;
+ pengine = 0;
+}
+
+void QVolatileImageData::beginDataAccess() const
+{
+ if (bitmap) {
+ bitmap->BeginDataAccess();
+ }
+}
+
+void QVolatileImageData::endDataAccess(bool readOnly) const
+{
+ if (bitmap) {
+ bitmap->EndDataAccess(readOnly);
+ }
+}
+
+bool QVolatileImageData::ensureFormat(QImage::Format format)
+{
+ if (image.isNull()) {
+ return false;
+ }
+ if (image.format() != format) {
+ CFbsBitmap *newBitmap = convertData(*this, format);
+ if (newBitmap && newBitmap != bitmap) {
+ delete bitmap;
+ bitmap = newBitmap;
+ updateImage();
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void *QVolatileImageData::duplicateNativeImage() const
+{
+ const_cast<QVolatileImageData *>(this)->ensureBitmap();
+ if (bitmap) {
+ if (bitmap->DisplayMode() == EColor16M) {
+ // slow path: needs rgb swapping
+ beginDataAccess();
+ QImage tmp = image.rgbSwapped();
+ endDataAccess(true);
+ return imageToBitmap(tmp);
+ } else if (bitmap->DisplayMode() == EGray2) {
+ // slow path: needs inverting pixels
+ beginDataAccess();
+ QImage tmp = image.copy();
+ endDataAccess(true);
+ tmp.invertPixels();
+ return imageToBitmap(tmp);
+ } else {
+ // fast path: just duplicate the bitmap
+ return duplicateBitmap(*bitmap);
+ }
+ }
+ return 0;
+}
+
+void QVolatileImageData::updateImage()
+{
+ if (bitmap) {
+ TSize size = bitmap->SizeInPixels();
+ beginDataAccess();
+ // Use existing buffer, no copy. The data address never changes so it
+ // is enough to do this whenever we have a new CFbsBitmap. N.B. never
+ // use const uchar* here, that would create a read-only image data which
+ // would make a copy in detach() even when refcount is 1.
+ image = QImage(reinterpret_cast<uchar *>(bitmap->DataAddress()),
+ size.iWidth, size.iHeight, bitmap->DataStride(),
+ qt_TDisplayMode2Format(bitmap->DisplayMode()));
+ endDataAccess(true);
+ } else {
+ image = QImage();
+ }
+}
+
+void QVolatileImageData::initWithBitmap(CFbsBitmap *source)
+{
+ bool needsCopy = bitmapNeedsCopy(source);
+ if (source->DisplayMode() == EColor16M) {
+ // EColor16M is BGR
+ CFbsBitmap *unswappedBmp = source;
+ if (needsCopy) {
+ unswappedBmp = rasterizeBitmap(source, source->DisplayMode());
+ }
+ unswappedBmp->BeginDataAccess();
+ TSize sourceSize = unswappedBmp->SizeInPixels();
+ QImage img((uchar *) unswappedBmp->DataAddress(),
+ sourceSize.iWidth, sourceSize.iHeight, unswappedBmp->DataStride(),
+ qt_TDisplayMode2Format(unswappedBmp->DisplayMode()));
+ img = img.rgbSwapped();
+ unswappedBmp->EndDataAccess(true);
+ bitmap = imageToBitmap(img);
+ if (needsCopy) {
+ delete unswappedBmp;
+ }
+ } else if (needsCopy) {
+ // Rasterize extended and compressed bitmaps.
+ bitmap = rasterizeBitmap(source, EColor16MAP);
+ } else if (source->DisplayMode() == EGray2) {
+ // The pixels will be inverted, must make a copy.
+ bitmap = rasterizeBitmap(source, source->DisplayMode());
+ } else {
+ // Efficient path: no pixel data copying. Just duplicate. This of course
+ // means the original bitmap's data may get modified, but that's fine
+ // and is in accordance with the QPixmap::fromSymbianCFbsBitmap() docs.
+ bitmap = duplicateBitmap(*source);
+ }
+ updateImage();
+ if (bitmap && bitmap->DisplayMode() == EGray2) {
+ // Symbian thinks set pixels are white/transparent, Qt thinks they are
+ // foreground/solid. Invert mono bitmaps so that masks work correctly.
+ beginDataAccess();
+ image.invertPixels();
+ endDataAccess();
+ }
+}
+
+void QVolatileImageData::applyMask(CFbsBitmap *mask)
+{
+ ensureFormat(QImage::Format_ARGB32_Premultiplied);
+ bool destroyMask = false;
+ if (bitmapNeedsCopy(mask)) {
+ mask = rasterizeBitmap(mask, EColor16MU);
+ if (!mask) {
+ return;
+ }
+ destroyMask = true;
+ }
+ mask->BeginDataAccess();
+ TSize maskSize = mask->SizeInPixels();
+ QImage maskImg((const uchar *) mask->DataAddress(), maskSize.iWidth, maskSize.iHeight,
+ mask->DataStride(), qt_TDisplayMode2Format(mask->DisplayMode()));
+ if (mask->DisplayMode() == EGray2) {
+ maskImg = maskImg.copy();
+ maskImg.invertPixels();
+ }
+ beginDataAccess();
+ image.setAlphaChannel(maskImg);
+ endDataAccess();
+ mask->EndDataAccess(true);
+ ensureImage();
+ if (destroyMask) {
+ delete mask;
+ }
+}
+
+void QVolatileImageData::ensureImage()
+{
+ if (bitmap && !image.isNull()) {
+ QImageData *imaged = image.data_ptr();
+ if (imaged->ref != 1 || imaged->ro_data) {
+ // This is bad, the imagedata got shared somehow. Detach, in order to
+ // have the next check fail and thus have 'image' recreated.
+ beginDataAccess();
+ image.detach();
+ endDataAccess(true);
+ }
+ }
+ if (bitmap && image.constBits() != reinterpret_cast<const uchar *>(bitmap->DataAddress())) {
+ // Should not ever get here. If we do it means that either 'image' has
+ // been replaced with a copy (e.g. because some QImage API assigned a
+ // new, regular QImage to *this) or the bitmap's data address changed
+ // unexpectedly.
+ qWarning("QVolatileImageData: Ptr mismatch");
+ // Recover by recreating the image so that it uses the bitmap as its buffer.
+ updateImage();
+ }
+}
+
+void QVolatileImageData::ensureBitmap()
+{
+ if (!bitmap && !image.isNull()) {
+ bitmap = imageToBitmap(image);
+ updateImage();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 8c8ffd4..de3577f 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -93,6 +93,9 @@ public:
TCoeInputCapabilities inputCapabilities();
+ void resetSplitViewWidget(bool keepInputWidget = false);
+ void ensureFocusWidgetVisible(QWidget *widget);
+
protected:
void timerEvent(QTimerEvent *timerEvent);
@@ -104,9 +107,11 @@ private:
void queueInputCapabilitiesChanged();
bool needsInputPanel();
void commitTemporaryPreeditString();
+ bool isWidgetVisible(QWidget *widget, int offset = 0);
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
+ void translateInputWidget();
// From MCoeFepAwareTextEditor
public:
@@ -155,9 +160,15 @@ private:
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
+ int m_splitViewResizeBy;
+ Qt::WindowStates m_splitViewPreviousWindowStates;
+ QRectF m_transformation;
+
friend class tst_QInputContext;
};
+Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable);
+
QT_END_NAMESPACE
#endif // QT_NO_IM
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 1bef64d..06dc25c 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -48,6 +48,8 @@
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
#include <qsymbianevent.h>
+#include <qlayout.h>
+#include <qdesktopwidget.h>
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
@@ -67,8 +69,25 @@
// that support text selection.
#define QT_EAknEditorFlagSelectionVisible 0x100000
+// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards.
+#define QT_EAknEditorFlagEnablePartialScreen 0x200000
+
QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
+{
+ S60->partial_keyboard = enable;
+
+ QInputContext *ic = 0;
+ if (QApplication::focusWidget()) {
+ ic = QApplication::focusWidget()->inputContext();
+ } else if (qApp && qApp->inputContext()) {
+ ic = qApp->inputContext();
+ }
+ if (ic)
+ ic->update();
+}
+
QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
: QInputContext(parent),
m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
@@ -80,19 +99,25 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_inlinePosition(0),
m_formatRetriever(0),
m_pointerHandler(0),
- m_hasTempPreeditString(false)
+ m_hasTempPreeditString(false),
+ m_splitViewResizeBy(0),
+ m_splitViewPreviousWindowStates(Qt::WindowNoState)
{
m_fepState->SetObjectProvider(this);
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- m_fepState->SetFlags(EAknEditorFlagDefault | QT_EAknEditorFlagSelectionVisible);
- else
- m_fepState->SetFlags(EAknEditorFlagDefault);
+ int defaultFlags = EAknEditorFlagDefault;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard) {
+ defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ }
+ defaultFlags |= QT_EAknEditorFlagSelectionVisible;
+ }
+ m_fepState->SetFlags(defaultFlags);
m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
m_fepState->SetDefaultCase( EAknEditorTextCase );
m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
- m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
+ m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
}
QCoeFepInputContext::~QCoeFepInputContext()
@@ -210,14 +235,33 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
return false;
switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ // Alphanumeric keypad doesn't like it when we click and text is still getting displayed
+ // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
+ // after the commit)
+ if (!m_preeditString.isEmpty()) {
+ commitCurrentString(true);
+
+ int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
+ QList<QInputMethodEvent::Attribute> selectAttributes;
+ selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant());
+ QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes);
+ sendEvent(selectEvent);
+ }
+ break;
case QEvent::KeyPress:
commitTemporaryPreeditString();
// fall through intended
case QEvent::KeyRelease:
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ //If proxy exists, always use hints from proxy.
+ QWidget *proxy = focusWidget()->focusProxy();
+ Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints();
+
switch (keyEvent->key()) {
case Qt::Key_F20:
- Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints());
+ Q_ASSERT(m_lastImHints == currentHints);
if (m_lastImHints & Qt::ImhHiddenText) {
// Special case in Symbian. On editors with secret text, F20 is for some reason
// considered to be a backspace.
@@ -247,7 +291,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
}
if (keyEvent->type() == QEvent::KeyPress
- && focusWidget()->inputMethodHints() & Qt::ImhHiddenText
+ && currentHints & Qt::ImhHiddenText
&& !keyEvent->text().isEmpty()) {
// Send some temporary preedit text in order to make text visible for a moment.
m_preeditString = keyEvent->text();
@@ -299,6 +343,23 @@ bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianE
// This should also happen for commands.
reset();
+ if (event->type() == QSymbianEvent::WindowServerEvent
+ && event->windowServerEvent()
+ && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged
+ && S60->splitViewLastWidget) {
+
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
+ const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+
+ if (alwaysResize) {
+ TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags;
+ if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+ ensureFocusWidgetVisible(S60->splitViewLastWidget);
+ if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible)
+ resetSplitViewWidget(true);
+ }
+ }
+
return false;
}
@@ -343,6 +404,175 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
return TCoeInputCapabilities(m_textCapabilities, this, 0);
}
+void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
+
+ if (!gv) {
+ return;
+ }
+
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ const bool alwaysResize = (gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ QWidget *windowToMove = gv->window();
+
+ bool userResize = gv->testAttribute(Qt::WA_Resized);
+
+ windowToMove->setUpdatesEnabled(false);
+
+ if (!alwaysResize) {
+ if (gv->scene()) {
+ if (gv->scene()->focusItem()) {
+ // Check if the widget contains cursorPositionChanged signal and disconnect from it.
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1)
+ disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
+
+ QGraphicsItem *rootItem = 0;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (rootItem)
+ rootItem->resetTransform();
+ }
+ } else {
+ if (m_splitViewResizeBy)
+ gv->resize(gv->rect().width(), m_splitViewResizeBy);
+ }
+ // Resizing might have led to widget losing its original windowstate.
+ // Restore previous window state.
+
+ if (m_splitViewPreviousWindowStates != windowToMove->windowState())
+ windowToMove->setWindowState(m_splitViewPreviousWindowStates);
+
+ windowToMove->setUpdatesEnabled(true);
+
+ gv->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+
+ m_splitViewResizeBy = 0;
+ if (!keepInputWidget) {
+ m_splitViewPreviousWindowStates = Qt::WindowNoState;
+ S60->splitViewLastWidget = 0;
+ }
+}
+
+// Checks if a given widget is visible in the splitview rect. The offset
+// parameter can be used to validate if moving widget upwards or downwards
+// by the offset would make a difference for the visibility.
+
+bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
+{
+ bool visible = false;
+ if (widget) {
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+ QWidget *window = QApplication::activeWindow();
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (gv && window) {
+ if (QGraphicsScene *scene = gv->scene()) {
+ if (QGraphicsItem *focusItem = scene->focusItem()) {
+ QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos());
+ cursorPos.setY(cursorPos.y() + offset);
+ if (splitViewRect.contains(cursorPos)) {
+ visible = true;
+ }
+ }
+ }
+ }
+ }
+ return visible;
+}
+
+// Ensure that the input widget is visible in the splitview rect.
+
+void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
+{
+ // Native side opening and closing its virtual keyboard when it changes the keyboard layout,
+ // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this.
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ // Graphicsviews that have vertical scrollbars should always be resized to the splitview area.
+ // Graphicsviews without scrollbars should be translated.
+
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (!gv)
+ return;
+
+ const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ const bool moveWithinVisibleArea = (S60->splitViewLastWidget != 0);
+
+ QWidget *windowToMove = gv ? gv : symControl->widget();
+ if (!windowToMove->isWindow())
+ windowToMove = windowToMove->window();
+ if (!windowToMove) {
+ return;
+ }
+
+ // When opening the keyboard (not moving within the splitview area), save the original
+ // window state. In some cases, ensuring input widget visibility might lead to window
+ // states getting changed.
+
+ if (!moveWithinVisibleArea) {
+ // Check if the widget contains cursorPositionChanged signal and connect to it.
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ if (gv->scene() && gv->scene()->focusItem()) {
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1)
+ connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
+ S60->splitViewLastWidget = widget;
+ m_splitViewPreviousWindowStates = windowToMove->windowState();
+ }
+
+ int windowTop = widget->window()->pos().y();
+
+ const bool userResize = widget->testAttribute(Qt::WA_Resized);
+
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+
+ // When resizing a window widget, it will lose its maximized window state.
+ // Native applications hide statuspane in splitview state, so lets move to
+ // fullscreen mode. This makes available area slightly bigger, which helps usability
+ // and greatly reduces event passing in orientation switch cases,
+ // as the statuspane size is not changing.
+
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(false);
+
+ if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
+ windowToMove->setWindowState(
+ (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
+ }
+
+ if (alwaysResize) {
+ if (!moveWithinVisibleArea) {
+ m_splitViewResizeBy = widget->height();
+ windowTop = widget->geometry().top();
+ widget->resize(widget->width(), splitViewRect.height() - windowTop);
+ }
+
+ if (gv->scene()) {
+ const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ gv->ensureVisible(microFocusRect);
+ }
+ } else {
+ translateInputWidget();
+ }
+
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(true);
+
+ widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+}
+
static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
{
QTextCharFormat qFormat;
@@ -362,7 +592,21 @@ void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities)
{
QWidget *w = focusWidget();
if (w) {
- Qt::InputMethodHints hints = w->inputMethodHints();
+ QWidget *proxy = w->focusProxy();
+ Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints();
+
+ // Since splitview support works like an input method hint, yet it is private flag,
+ // we need to update its state separately.
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ TInt currentFlags = m_fepState->Flags();
+ if (S60->partial_keyboard)
+ currentFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ else
+ currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen;
+ if (currentFlags != m_fepState->Flags())
+ m_fepState->SetFlags(currentFlags);
+ }
+
if (hints != m_lastImHints) {
m_lastImHints = hints;
applyHints(hints);
@@ -474,10 +718,12 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
m_fepState->SetPermittedCases(flags);
ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- flags = QT_EAknEditorFlagSelectionVisible;
- else
- flags = 0;
+ flags = 0;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard)
+ flags |= QT_EAknEditorFlagEnablePartialScreen;
+ flags |= QT_EAknEditorFlagSelectionVisible;
+ }
if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
|| hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
flags |= EAknEditorFlagFixedCase;
@@ -513,6 +759,8 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
} else if (needsCharMap) {
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly)) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
} else {
m_fepState->SetSpecialCharacterTableResourceId(0);
}
@@ -604,6 +852,47 @@ void QCoeFepInputContext::ensureInputCapabilitiesChanged()
m_pendingInputCapabilitiesChanged = false;
}
+void QCoeFepInputContext::translateInputWidget()
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget);
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+ QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ QPolygon cursorP = gv->mapFromScene(cursor);
+ QRectF vkbRect = QRectF(splitViewRect.bottomLeft(), qApp->desktop()->rect().bottomRight());
+ if (cursor.isEmpty() || vkbRect.isEmpty())
+ return;
+
+ // Fetch root item (i.e. graphicsitem with no parent)
+ QGraphicsItem *rootItem = 0;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (!rootItem)
+ return;
+
+ m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
+
+ // Do nothing if the cursor is visible in the splitview area.
+ if (splitViewRect.contains(cursorP.boundingRect()))
+ return;
+
+ // New Y position should be ideally at the center of the splitview area.
+ // If that would expose unpainted canvas, limit the tranformation to the visible scene bottom.
+
+ const qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom() + m_transformation.height();
+ qreal dy = -(qMin(maxY, (cursor.bottom() - vkbRect.top() / 2)));
+
+ // Do not allow transform above screen top.
+ if (m_transformation.height() + dy > 0)
+ return;
+
+ rootItem->setTransform(QTransform::fromTranslate(0, dy), true);
+}
+
void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/,
MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp
index 063aefd..f083e51 100644
--- a/src/gui/inputmethod/qinputcontext.cpp
+++ b/src/gui/inputmethod/qinputcontext.cpp
@@ -355,9 +355,10 @@ void QInputContext::widgetDestroyed(QWidget *widget)
in complex input method. In the case, call QInputContext::reset()
to ensure proper termination of inputting.
- You must not send any QInputMethodEvent except empty InputMethodEnd event using
- QInputContext::reset() at reimplemented reset(). It will break
- input state consistency.
+ In a reimplementation of reset(), you must not send any
+ QInputMethodEvent containing preedit text. You can only commit
+ string and attributes; otherwise, you risk breaking input state
+ consistency.
*/
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp
index c857670..2ccf792 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/gui/itemviews/qheaderview.cpp
@@ -643,8 +643,12 @@ int QHeaderView::sectionSize(int logicalIndex) const
}
/*!
- Returns the section position of the given \a logicalIndex, or -1 if the
- section is hidden.
+
+ Returns the section position of the given \a logicalIndex, or -1
+ if the section is hidden. The position is measured in pixels from
+ the first visible item's top-left corner to the top-left corner of
+ the item with \a logicalIndex. The measurement is along the x-axis
+ for horizontal headers and along the y-axis for vertical headers.
\sa sectionViewportPosition()
*/
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp
index 94e3b76..61a935f 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/gui/itemviews/qlistwidget.cpp
@@ -1500,7 +1500,9 @@ void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags com
}
/*!
- Returns a pointer to the item at the coordinates \a p.
+ Returns a pointer to the item at the coordinates \a p. The coordinates
+ are relative to the list widget's \l{QAbstractScrollArea::}{viewport()}.
+
*/
QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
{
@@ -1514,6 +1516,9 @@ QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
\overload
Returns a pointer to the item at the coordinates (\a x, \a y).
+ The coordinates are relative to the list widget's
+ \l{QAbstractScrollArea::}{viewport()}.
+
*/
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index e54cbd2..9f89bf5 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -227,7 +227,7 @@ public:
void _q_sourceColumnsRemoved(const QModelIndex &source_parent,
int start, int end);
- void clear_mapping();
+ void _q_clearMapping();
void sort();
bool update_source_sort_column();
@@ -281,7 +281,7 @@ typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap;
void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed()
{
QAbstractProxyModelPrivate::_q_sourceModelDestroyed();
- clear_mapping();
+ _q_clearMapping();
}
void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent)
@@ -293,7 +293,7 @@ void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source
}
}
-void QSortFilterProxyModelPrivate::clear_mapping()
+void QSortFilterProxyModelPrivate::_q_clearMapping()
{
// store the persistent indexes
QModelIndexPairList source_indexes = store_persistent_indexes();
@@ -1223,7 +1223,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset()
{
Q_Q(QSortFilterProxyModel);
invalidatePersistentIndexes();
- clear_mapping();
+ _q_clearMapping();
// All internal structures are deleted in clear()
q->endResetModel();
update_source_sort_column();
@@ -1519,6 +1519,7 @@ QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent)
d->filter_column = 0;
d->filter_role = Qt::DisplayRole;
d->dynamic_sortfilter = false;
+ connect(this, SIGNAL(modelReset()), this, SLOT(_q_clearMapping()));
}
/*!
@@ -1620,7 +1621,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
- d->clear_mapping();
+ d->_q_clearMapping();
endResetModel();
if (d->update_source_sort_column() && d->dynamic_sortfilter)
d->sort();
@@ -2311,7 +2312,7 @@ void QSortFilterProxyModel::clear()
{
Q_D(QSortFilterProxyModel);
emit layoutAboutToBeChanged();
- d->clear_mapping();
+ d->_q_clearMapping();
emit layoutChanged();
}
@@ -2326,7 +2327,7 @@ void QSortFilterProxyModel::invalidate()
{
Q_D(QSortFilterProxyModel);
emit layoutAboutToBeChanged();
- d->clear_mapping();
+ d->_q_clearMapping();
emit layoutChanged();
}
diff --git a/src/gui/itemviews/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h
index 09fd20f..afeaa69 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.h
+++ b/src/gui/itemviews/qsortfilterproxymodel.h
@@ -189,6 +189,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_clearMapping())
};
QT_END_NAMESPACE
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 0d1473d..eb54bac 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -263,6 +263,11 @@ QStyledItemDelegate::~QStyledItemDelegate()
The default implementation uses the QLocale::toString to convert \a value into
a QString.
+
+ This function is not called for empty model indices, i.e., indices for which
+ the model returns an invalid QVariant.
+
+ \sa QAbstractItemModel::data()
*/
QString QStyledItemDelegate::displayText(const QVariant &value, const QLocale& locale) const
{
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index f1f3236..c0573bb 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -2753,6 +2753,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
int start = -1;
int end = -1;
+ int indexRow = index.row();
int count = d->header->count();
bool emptyHeader = (count == 0);
QModelIndex parent = index.parent();
@@ -2789,7 +2790,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
int logicalColumn = emptyHeader ? column : d->header->logicalIndex(column);
if (d->header->isSectionHidden(logicalColumn))
continue;
- QModelIndex idx = d->model->index(index.row(), logicalColumn, parent);
+ QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);
if (idx.isValid()) {
QWidget *editor = d->editorForIndex(idx).editor;
if (editor && d->persistent.contains(editor)) {
@@ -3224,14 +3225,14 @@ int QTreeViewPrivate::itemHeight(int item) const
if (viewItems.isEmpty())
return 0;
const QModelIndex &index = viewItems.at(item).index;
+ if (!index.isValid())
+ return 0;
int height = viewItems.at(item).height;
- if (height <= 0 && index.isValid()) {
+ if (height <= 0) {
height = q_func()->indexRowSizeHint(index);
viewItems[item].height = height;
}
- if (!index.isValid() || height < 0)
- return 0;
- return height;
+ return qMax(height, 0);
}
diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp
index 4db29d6..2ea9a43 100644
--- a/src/gui/itemviews/qtreewidget.cpp
+++ b/src/gui/itemviews/qtreewidget.cpp
@@ -2830,7 +2830,8 @@ void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column,
/*!
- Returns a pointer to the item at the coordinates \a p.
+ Returns a pointer to the item at the coordinates \a p. The coordinates
+ are relative to the tree widget's \l{QAbstractScrollArea::}{viewport()}.
\sa visualItemRect()
*/
@@ -2844,7 +2845,8 @@ QTreeWidgetItem *QTreeWidget::itemAt(const QPoint &p) const
\fn QTreeWidgetItem *QTreeWidget::itemAt(int x, int y) const
\overload
- Returns a pointer to the item at the coordinates (\a x, \a y).
+ Returns a pointer to the item at the coordinates (\a x, \a y). The coordinates
+ are relative to the tree widget's \l{QAbstractScrollArea::}{viewport()}.
*/
/*!
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index f9c84c1..467eb9b 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -111,6 +111,8 @@ win32 {
}
symbian {
+ exists($${EPOCROOT}epoc32/include/platform/mw/akntranseffect.h): DEFINES += QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
+
SOURCES += \
kernel/qapplication_s60.cpp \
kernel/qeventdispatcher_s60.cpp \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 59aec91..f906bbf 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -128,6 +128,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
//#define ALIEN_DEBUG
+#if defined(Q_OS_SYMBIAN)
+#include "qt_s60_p.h"
+#endif
+
static void initResources()
{
#if defined(Q_WS_WINCE)
@@ -2432,6 +2436,11 @@ bool QApplication::event(QEvent *e)
{
Q_D(QApplication);
if(e->type() == QEvent::Close) {
+#if defined(Q_OS_SYMBIAN)
+ // In order to have proper application-exit effects on Symbian, certain
+ // native APIs have to be called _before_ closing/destroying the widgets.
+ bool effectStarted = qt_beginFullScreenEffect();
+#endif
QCloseEvent *ce = static_cast<QCloseEvent*>(e);
ce->accept();
closeAllWindows();
@@ -2445,8 +2454,14 @@ bool QApplication::event(QEvent *e)
break;
}
}
- if(ce->isAccepted())
+ if (ce->isAccepted()) {
return true;
+ } else {
+#if defined(Q_OS_SYMBIAN)
+ if (effectStarted)
+ qt_abortFullScreenEffect();
+#endif
+ }
} else if(e->type() == QEvent::LanguageChange) {
#ifndef QT_NO_TRANSLATION
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 43634ef..3d2c9d6 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -599,6 +599,8 @@ public:
int pressureSupported;
int maxTouchPressure;
QList<QTouchEvent::TouchPoint> appAllTouchPoints;
+
+ bool useTranslucentEGLSurfaces;
#endif
private:
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 6bddb19..6620efd 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -87,7 +87,7 @@
#include <hal.h>
#include <hal_data.h>
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
#include <graphics/wstfxconst.h>
#endif
@@ -96,6 +96,9 @@ QT_BEGIN_NAMESPACE
// Goom Events through Window Server
static const int KGoomMemoryLowEvent = 0x10282DBF;
static const int KGoomMemoryGoodEvent = 0x20026790;
+// Split view open/close events from AVKON
+static const int KSplitViewOpenEvent = 0x2001E2C0;
+static const int KSplitViewCloseEvent = 0x2001E2C1;
#if defined(QT_DEBUG)
static bool appNoGrab = false; // Grabbing enabled
@@ -139,6 +142,60 @@ void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, boo
// Ensure that control rectangle is updated
static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange();
}
+
+bool QS60Data::setRecursiveDecorationsVisibility(QWidget *window, Qt::WindowStates newState)
+{
+ // Show statusbar:
+ // Topmost parent: Show unless fullscreen/minimized.
+ // Child windows: Follow topmost parent, unless fullscreen, in which case do not show statusbar
+ // Show CBA:
+ // Topmost parent: Show unless fullscreen/minimized.
+ // Exception: Show if fullscreen with Qt::WindowSoftkeysVisibleHint.
+ // Child windows:
+ // Minimized: Unclear if there is an use case for having focused minimized window at all.
+ // Always follow topmost parent just to be safe.
+ // Maximized and normal: follow topmost parent.
+ // Exception: If topmost parent is not showing CBA, show CBA if any softkey actions are
+ // defined.
+ // Fullscreen: Show only if Qt::WindowSoftkeysVisibleHint set.
+
+ Qt::WindowStates comparisonState = newState;
+ QWidget *parentWindow = window->parentWidget();
+ if (parentWindow) {
+ while (parentWindow->parentWidget())
+ parentWindow = parentWindow->parentWidget();
+ comparisonState = parentWindow->windowState();
+ } else {
+ parentWindow = window;
+ }
+
+ bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen;
+ const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint));
+
+ // Do extra checking for child windows
+ if (window->parentWidget()) {
+ if (newState & Qt::WindowFullScreen) {
+ decorationsVisible = false;
+ if (window->windowFlags() & Qt::WindowSoftkeysVisibleHint)
+ buttonGroupVisibility = true;
+ else
+ buttonGroupVisibility = false;
+ } else if (!(newState & Qt::WindowMinimized) && !buttonGroupVisibility) {
+ for (int i = 0; i < window->actions().size(); ++i) {
+ if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) {
+ buttonGroupVisibility = true;
+ break;
+ }
+ }
+ }
+ }
+
+ S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility);
+
+ return decorationsVisible;
+}
#endif
void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
@@ -158,6 +215,12 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
widget->repaint();
}
} else {
+ // In certain special scenarios we may get an ENotVisible event
+ // without a previous EPartiallyVisible. The backingstore must
+ // still be destroyed, hence the registerWidget() call below.
+ if (backingStore.data() && widget->internalWinId()
+ && qt_widget_private(widget)->maybeBackingStore() == backingStore.data())
+ backingStore.registerWidget(widget);
backingStore.unregisterWidget(widget);
// In order to ensure that any resources used by the window surface
// are immediately freed, we flush the WSERV command buffer.
@@ -401,6 +464,8 @@ QSymbianControl::QSymbianControl(QWidget *w)
, m_longTapDetector(0)
, m_ignoreFocusChanged(0)
, m_symbianPopupIsOpen(0)
+ , m_inExternalScreenOverride(false)
+ , m_lastStatusPaneVisibility(0)
{
}
@@ -408,9 +473,11 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
{
if (!desktop)
{
- if (isWindowOwning || !qwidget->parentWidget())
- CreateWindowL(S60->windowGroup());
- else
+ if (isWindowOwning || !qwidget->parentWidget()
+ || qwidget->parentWidget()->windowType() == Qt::Desktop) {
+ RWindowGroup &wg(S60->windowGroup(qwidget));
+ CreateWindowL(wg);
+ } else {
/**
* TODO: in order to avoid creating windows for all ancestors of
* this widget up to the root window, the parameter passed to
@@ -420,6 +487,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
* is created for a widget between this one and the root window.
*/
CreateWindowL(qwidget->parentWidget()->winId());
+ }
// Necessary in order to be able to track the activation status of
// the control's window
@@ -432,7 +500,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
DrawableWindow()->SetPointerGrab(ETrue);
}
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
if (OwnsWindow()) {
TTfxWindowPurpose windowPurpose(ETfxPurposeNone);
switch (qwidget->windowType()) {
@@ -452,7 +520,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
windowPurpose = ETfxPurposeSplashScreenWindow;
break;
default:
- windowPurpose = (isWindowOwning || !qwidget->parentWidget())
+ windowPurpose = (isWindowOwning || !qwidget->parentWidget() || qwidget->parentWidget()->windowType() == Qt::Desktop)
? ETfxPurposeWindow : ETfxPurposeChildWindow;
break;
}
@@ -484,11 +552,52 @@ void QSymbianControl::setWidget(QWidget *w)
{
qwidget = w;
}
+
+QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
+{
+ QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QSize wsize = qwidget->size();
+ TSize size = Size();
+ if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
+ qreal x = pos.x();
+ qreal y = pos.y();
+ pos.setX(size.iHeight - y);
+ pos.setY(x);
+ }
+ }
+ return pos;
+}
+
+TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
+{
+ TRect rect = controlRect;
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
+ QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
+ if (a.x() < b.x()) {
+ rect.iTl.iX = a.x();
+ rect.iBr.iX = b.x();
+ } else {
+ rect.iTl.iX = b.x();
+ rect.iBr.iX = a.x();
+ }
+ if (a.y() < b.y()) {
+ rect.iTl.iY = a.y();
+ rect.iBr.iY = b.y();
+ } else {
+ rect.iTl.iY = b.y();
+ rect.iBr.iY = a.y();
+ }
+ }
+ return rect;
+}
+
void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
{
QWidget *alienWidget;
- QPoint widgetPos = QPoint(aPenEventLocation.iX, aPenEventLocation.iY);
- QPoint globalPos = QPoint(aPenEventScreenLocation.iX,aPenEventScreenLocation.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
+ QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
@@ -503,7 +612,7 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons
void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
{
QApplicationPrivate *d = QApplicationPrivate::instance();
- QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
+ QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
qreal pressure;
if(d->pressureSupported
&& event->Pressure() > 0) //workaround for misconfigured HAL
@@ -604,7 +713,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
S60->lastCursorPos = globalPos;
@@ -983,14 +1092,15 @@ TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEven
}
}
//clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ int screenNumber = S60->screenNumberForWidget(qwidget);
if (x < 0)
x = 0;
- else if (x >= S60->screenWidthInPixels)
- x = S60->screenWidthInPixels - 1;
+ else if (x >= S60->screenWidthInPixelsForScreen[screenNumber])
+ x = S60->screenWidthInPixelsForScreen[screenNumber] - 1;
if (y < 0)
y = 0;
- else if (y >= S60->screenHeightInPixels)
- y = S60->screenHeightInPixels - 1;
+ else if (y >= S60->screenHeightInPixelsForScreen[screenNumber])
+ y = S60->screenHeightInPixelsForScreen[screenNumber] - 1;
TPoint epos(x, y);
TPoint cpos = epos - PositionRelativeToScreen();
fakeEvent.iPosition = cpos;
@@ -1069,6 +1179,9 @@ void QSymbianControl::Draw(const TRect& controlRect) const
Q_ASSERT(window);
QTLWExtra *topExtra = window->d_func()->maybeTopData();
Q_ASSERT(topExtra);
+
+ TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
+
if (!topExtra->inExpose) {
topExtra->inExpose = true;
if (!qwidget->isWindow()) {
@@ -1079,7 +1192,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
gc.SetBrushColor(TRgb(0, 0, 0, 0));
gc.Clear(controlRect);
}
- QRect exposeRect = qt_TRect2QRect(controlRect);
+ QRect exposeRect = qt_TRect2QRect(wcontrolRect);
qwidget->d_func()->syncBackingStore(exposeRect);
topExtra->inExpose = false;
}
@@ -1092,7 +1205,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
}
@@ -1124,7 +1237,8 @@ void QSymbianControl::Draw(const TRect& controlRect) const
// Do nothing
break;
case QWExtra::Blit:
- if (qwidget->d_func()->isOpaque)
+ case QWExtra::BlitWriteAlpha:
+ if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
break;
@@ -1146,7 +1260,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
// The draw ops aren't actually sent to WSERV until the graphics
// context is deactivated, which happens in the function calling
// this one. We therefore delay the delivery of endNativePaintEvent,
@@ -1159,36 +1273,63 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
}
+void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
+{
+ QRect cr = qwidget->geometry();
+ QSize oldSize(cr.size());
+ cr.setSize(newSize);
+ qwidget->data->crect = cr;
+ if (qwidget->isVisible()) {
+ QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
+ bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = true;
+ QResizeEvent e(newSize, oldSize);
+ qt_sendSpontaneousEvent(qwidget, &e);
+ if (!qwidget->testAttribute(Qt::WA_StaticContents))
+ qwidget->d_func()->syncBackingStore();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = false;
+ } else {
+ if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
+ QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+ QApplication::postEvent(qwidget, e);
+ }
+ }
+}
+
void QSymbianControl::SizeChanged()
{
CCoeControl::SizeChanged();
+ // When FixNativeOrientation had been called, the RWindow/CCoeControl size
+ // and the surface/QWidget size have nothing to do with each other.
+ if (qwidget->d_func()->fixNativeOrientationCalled)
+ return;
+
QSize oldSize = qwidget->size();
QSize newSize(Size().iWidth, Size().iHeight);
if (oldSize != newSize) {
- QRect cr = qwidget->geometry();
- cr.setSize(newSize);
- qwidget->data->crect = cr;
- if (qwidget->isVisible()) {
- QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
- bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- qt_sendSpontaneousEvent(qwidget, &e);
- if (!qwidget->testAttribute(Qt::WA_StaticContents))
- qwidget->d_func()->syncBackingStore();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(qwidget, e);
+ // Enforce the proper size for fullscreen widgets on the secondary screen.
+ const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+ const int screenNumber = S60->screenNumberForWidget(qwidget);
+ if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
+ int screenWidth = S60->screenWidthInPixelsForScreen[screenNumber];
+ int screenHeight = S60->screenHeightInPixelsForScreen[screenNumber];
+ TSize screenSize(screenWidth, screenHeight);
+ if (screenWidth > 0 && screenHeight > 0 && screenSize != Size()) {
+ m_inExternalScreenOverride = true;
+ SetExtent(TPoint(0, 0), screenSize);
+ return;
}
}
+
+ qwidgetResize_helper(newSize);
}
+ m_inExternalScreenOverride = false;
+
// CCoeControl::SetExtent calls SizeChanged, but does not call
// PositionChanged, so we call it here to ensure that the widget's
// position is updated.
@@ -1224,6 +1365,11 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
return;
+#ifdef Q_WS_S60
+ if (S60->splitViewLastWidget)
+ return;
+#endif
+
// Popups never get focused, but still receive the FocusChanged when they are hidden.
if (QApplicationPrivate::popupWidgets != 0
|| (qwidget->windowType() & Qt::Popup) == Qt::Popup)
@@ -1243,16 +1389,8 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
qwidget->d_func()->setWindowIcon_sys(true);
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
#ifdef Q_WS_S60
- // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
- QWidget *const window = qwidget->window();
- if (!window->parentWidget()) { // Only top level native windows have control over cba/status pane
- const bool decorationsVisible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
- const bool statusPaneVisibility = decorationsVisible;
- const bool isFullscreen = window->windowState() & Qt::WindowFullScreen;
- const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint;
- const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaVisibilityHint));
- S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
- }
+ if (qwidget->isWindow())
+ S60->setRecursiveDecorationsVisibility(qwidget, qwidget->windowState());
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
bool focusedControlFound = false;
@@ -1302,11 +1440,64 @@ void QSymbianControl::handleClientAreaChange()
}
}
+bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
+ bool returnValue = true;
+ //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
+ if (!qwidget->isActiveWindow()
+ || !qwidget->isVisible()
+ || !qwidget->isAncestorOf(widget)) {
+
+ returnValue = false;
+ }
+ return returnValue;
+}
+
void QSymbianControl::HandleResourceChange(int resourceType)
{
switch (resourceType) {
+ case KSplitViewCloseEvent: //intentional fall-through
+ case KSplitViewOpenEvent: {
+#if !defined(QT_NO_IM) && defined(Q_WS_S60)
+
+ //Fetch widget getting the text input
+ QWidget *widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QApplicationPrivate::popupWidgets) {
+ widget = QApplication::activePopupWidget()->focusWidget();
+ if (!widget) {
+ widget = QApplication::activePopupWidget();
+ }
+ } else {
+ widget = QApplicationPrivate::focus_widget;
+ if (!widget) {
+ widget = qwidget;
+ }
+ }
+ }
+ if (widget) {
+ QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
+ if (!ic) {
+ ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
+ }
+ if (ic && isSplitViewWidget(widget)) {
+ if (resourceType == KSplitViewCloseEvent) {
+ ic->resetSplitViewWidget();
+ } else {
+ ic->ensureFocusWidgetVisible(widget);
+ }
+ }
+ }
+#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
+ }
+ break;
case KInternalStatusPaneChange:
- handleClientAreaChange();
+ // When status pane is not visible, only handle client area change if status pane was
+ // previously visible, as size changes to hidden status pane should not affect
+ // client area.
+ if (S60->statusPane() && (S60->statusPane()->IsVisible() || m_lastStatusPaneVisibility)) {
+ m_lastStatusPaneVisibility = S60->statusPane()->IsVisible();
+ handleClientAreaChange();
+ }
if (IsFocused() && IsVisible()) {
qwidget->d_func()->setWindowIcon_sys(true);
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
@@ -1320,8 +1511,10 @@ void QSymbianControl::HandleResourceChange(int resourceType)
{
handleClientAreaChange();
// Send resize event to trigger desktopwidget workAreaResized signal
- QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &e);
+ if (qt_desktopWidget) {
+ QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
+ QApplication::sendEvent(qt_desktopWidget, &e);
+ }
break;
}
#endif
@@ -1380,6 +1573,55 @@ bool QSymbianControl::isControlActive()
return IsActivated() ? true : false;
}
+void QSymbianControl::ensureFixNativeOrientation()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
+ if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
+ return;
+ if (S60->screenNumberForWidget(qwidget) > 0)
+ return;
+ const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
+ const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
+ const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
+ if (isFullScreen && isFixEnabled) {
+ const bool surfaceBasedGs =
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
+ if (!surfaceBasedGs)
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ if (!isFixed && surfaceBasedGs) {
+ if (Window().FixNativeOrientation() == KErrNone) {
+ qwidget->d_func()->fixNativeOrientationCalled = true;
+ // The EGL window surface is now fixed to the native orientation
+ // of the device, no matter what size we pass when creating it.
+ // Enforce the same size for the QWidget too. For the underlying
+ // CCoeControl and RWindow it is up to the system to resize them
+ // when the standard auto-rotation mechanism is in use, we must not
+ // change that behavior by forcing any size for those. In practice
+ // this means that the QWidget and the underlying native control
+ // dimensions will be out of sync when FixNativeOrientation was
+ // called and the device is turned to the non-native (typically
+ // landscape) orientation. The pointer event handling and certain
+ // functions like Draw() will need to compensate for this.
+ QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
+ if (qwidget->size() != newSize)
+ qwidgetResize_helper(newSize);
+ } else {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ }
+ }
+ } else if (isFixed) {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ qwidget->d_func()->fixNativeOrientationCalled = false;
+ qwidget->hide();
+ qwidget->d_func()->create_sys(0, false, true);
+ qwidget->show();
+ }
+#else
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+#endif
+}
+
/*!
\typedef QApplication::QS60MainApplicationFactory
\since 4.6
@@ -1586,10 +1828,36 @@ void qt_init(QApplicationPrivate * /* priv */, int)
systemFont.setFamily(systemFont.defaultFamily());
QApplicationPrivate::setSystemFont(systemFont);
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
-#endif
+#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
+
+ const TUid KIvePropertyCat = {0x2726beef};
+ enum TIvePropertyChipType {
+ EVCBCM2727B1 = 0x00000000,
+ EVCBCM2763A0 = 0x04000100,
+ EVCBCM2763B0 = 0x04000102,
+ EVCBCM2763C0 = 0x04000103,
+ EVCBCM2763C1 = 0x04000104,
+ EVCBCMUnknown = 0x7fffffff
+ };
+
+ TInt chipType = EVCBCMUnknown;
+ if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
+ if (chipType == EVCBCM2727B1) {
+ // We have only 32MB GPU memory. Use raster surfaces
+ // for transparent TLWs.
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+ } else {
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+#else
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+#endif
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
@@ -1651,6 +1919,9 @@ void qt_cleanup()
S60->setButtonGroupContainer(0);
#endif
+ // Call EndFullScreen() to prevent confusing the system effect state machine.
+ qt_endFullScreenEffect();
+
if (S60->qtOwnsS60Environment) {
// Restore the S60 framework trap handler. See qt_init().
User::SetTrapHandler(S60->s60InstalledTrapHandler);
@@ -1686,7 +1957,7 @@ bool QApplicationPrivate::modalState()
void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeEnter);
#endif
if (widget) {
@@ -1704,7 +1975,7 @@ void QApplicationPrivate::enterModal_sys(QWidget *widget)
void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeExit);
#endif
if (widget) {
@@ -1979,7 +2250,10 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
return 1;
}
break;
- case EEventScreenDeviceChanged:
+ case EEventScreenDeviceChanged: // fallthrough
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ case EEventDisplayChanged:
+#endif
if (callSymbianEventFilters(symbianEvent))
return 1;
if (S60)
@@ -2019,7 +2293,8 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
}
#endif
#ifdef QT_SOFTKEYS_ENABLED
- QSoftKeyManager::updateSoftKeys();
+ if (!CEikonEnv::Static()->EikAppUi()->IsDisplayingMenuOrDialog())
+ QSoftKeyManager::updateSoftKeys();
#endif
break;
case EEventFocusLost:
@@ -2385,7 +2660,9 @@ void QApplication::restoreOverrideCursor()
void QApplicationPrivate::_q_aboutToQuit()
{
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ qt_beginFullScreenEffect();
+
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
// Send the shutdown tfx command
S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
#endif
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 6e89ceb..913bc7e 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -3779,16 +3779,32 @@ bool QETWidget::translateConfigEvent(const MSG &msg)
QApplication::sendSpontaneousEvent(this, &e);
hideChildren(true);
}
- } else if (msg.wParam != SIZE_MINIMIZED && isMinimized()) {
+ } else if (msg.wParam != SIZE_MINIMIZED) {
+ bool window_state_changed = false;
+ Qt::WindowStates oldstate = Qt::WindowStates(dataPtr()->window_state);
+ if (isMinimized()) {
#ifndef Q_WS_WINCE
- const QString title = windowTitle();
- if (!title.isEmpty())
- d_func()->setWindowTitle_helper(title);
+ const QString title = windowTitle();
+ if (!title.isEmpty())
+ d_func()->setWindowTitle_helper(title);
#endif
- data->window_state &= ~Qt::WindowMinimized;
- showChildren(true);
- QShowEvent e;
- QApplication::sendSpontaneousEvent(this, &e);
+ data->window_state &= ~Qt::WindowMinimized;
+ showChildren(true);
+ QShowEvent e;
+ QApplication::sendSpontaneousEvent(this, &e);
+ // Capture SIZE_MAXIMIZED and SIZE_RESTORED without preceding WM_SYSCOMMAND
+ // (Aero Snap on Win7)
+ } else if (msg.wParam == SIZE_MAXIMIZED && !isMaximized()) {
+ data->window_state |= Qt::WindowMaximized;
+ window_state_changed = true;
+ } else if (msg.wParam == SIZE_RESTORED && isMaximized()) {
+ data->window_state &= ~(Qt::WindowMaximized);
+ window_state_changed = true;
+ }
+ if (window_state_changed) {
+ QWindowStateChangeEvent e(oldstate);
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
}
}
if (msg.wParam != SIZE_MINIMIZED && oldSize != newSize) {
@@ -3820,7 +3836,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg)
QApplication::postEvent(this, e);
}
}
-} else if (msg.message == WM_MOVE) { // move event
+ } else if (msg.message == WM_MOVE) { // move event
int a = (int) (short) LOWORD(msg.lParam);
int b = (int) (short) HIWORD(msg.lParam);
QPoint oldPos = geometry().topLeft();
diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp
index 52b9663..ea41165 100644
--- a/src/gui/kernel/qclipboard_win.cpp
+++ b/src/gui/kernel/qclipboard_win.cpp
@@ -52,6 +52,7 @@
#include "qt_windows.h"
#include "qdnd_p.h"
#include <private/qwidget_p.h>
+#include <private/qsystemlibrary_p.h>
QT_BEGIN_NAMESPACE
@@ -70,6 +71,9 @@ void QtCeFlushClipboard();
#endif
+typedef BOOL (WINAPI *PtrIsHungAppWindow)(HWND);
+
+static PtrIsHungAppWindow ptrIsHungAppWindow = 0;
class QClipboardWatcher : public QInternalMimeData {
public:
@@ -327,9 +331,16 @@ bool QClipboard::event(QEvent *e)
d->releaseIData();
propagate = true;
}
-
if (propagate && d->nextClipboardViewer) {
- SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
+ if (ptrIsHungAppWindow == 0) {
+ QSystemLibrary library(QLatin1String("User32"));
+ ptrIsHungAppWindow = (PtrIsHungAppWindow)library.resolve("IsHungAppWindow");
+ }
+ if (ptrIsHungAppWindow && ptrIsHungAppWindow(d->nextClipboardViewer)) {
+ qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
+ } else {
+ SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
+ }
}
return true;
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 9c110fd..406e6d4 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -89,6 +89,8 @@ QT_END_NAMESPACE
QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
if (!widget)
return NO; // This should happen only for qt_root_win
+ if (QApplicationPrivate::isBlockedByModal(widget))
+ return NO;
bool isToolTip = (widget->windowType() == Qt::ToolTip);
bool isPopup = (widget->windowType() == Qt::Popup);
@@ -100,6 +102,8 @@ QT_END_NAMESPACE
QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
if (!widget)
return NO; // This should happen only for qt_root_win
+ if ([self isSheet])
+ return NO;
bool isToolTip = (widget->windowType() == Qt::ToolTip);
bool isPopup = (widget->windowType() == Qt::Popup);
@@ -153,6 +157,20 @@ QT_END_NAMESPACE
[NSApp terminate:sender];
}
+- (void)setLevel:(NSInteger)windowLevel
+{
+ // Cocoa will upon activating/deactivating applications level modal
+ // windows up and down, regardsless of any explicit set window level.
+ // To ensure that modal stays-on-top dialogs actually stays on top after
+ // the application is activated (and therefore stacks in front of
+ // other stays-on-top windows), we need to add this little special-case override:
+ QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+ if (widget && widget->isModal() && (widget->windowFlags() & Qt::WindowStaysOnTopHint))
+ [super setLevel:NSPopUpMenuWindowLevel];
+ else
+ [super setLevel:windowLevel];
+}
+
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSApplicationDefined) {
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 749472a..d9f428c 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -1115,7 +1115,7 @@ static int qCocoaViewCount = 0;
- (BOOL)resignFirstResponder
{
if (!qwidget)
- return NO;
+ return YES;
// Seems like the following test only triggers if this
// view is inside a QMacNativeWidget:
if (qwidget == QApplication::focusWidget())
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 3653ae2..62a4d40 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -44,36 +44,67 @@
#include "qwidget_p.h"
#include "qt_s60_p.h"
#include <w32std.h>
-
-#include "hal.h"
-#include "hal_data.h"
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+#include <graphics/displaycontrol.h>
+#endif
QT_BEGIN_NAMESPACE
-class QDesktopWidgetPrivate : public QWidgetPrivate
+extern int qt_symbian_create_desktop_on_screen;
+
+class QSingleDesktopWidget : public QWidget
+{
+public:
+ QSingleDesktopWidget();
+ ~QSingleDesktopWidget();
+};
+
+QSingleDesktopWidget::QSingleDesktopWidget()
+ : QWidget(0, Qt::Desktop)
+{
+}
+
+QSingleDesktopWidget::~QSingleDesktopWidget()
{
+ const QObjectList &childList = children();
+ for (int i = childList.size(); i > 0 ;) {
+ --i;
+ childList.at(i)->setParent(0);
+ }
+}
+class QDesktopWidgetPrivate : public QWidgetPrivate
+{
public:
QDesktopWidgetPrivate();
~QDesktopWidgetPrivate();
-
static void init(QDesktopWidget *that);
static void cleanup();
+ static void init_sys();
static int screenCount;
static int primaryScreen;
static QVector<QRect> *rects;
static QVector<QRect> *workrects;
+ static QVector<QWidget *> *screens;
static int refcount;
+
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ static MDisplayControl *displayControl;
+#endif
};
int QDesktopWidgetPrivate::screenCount = 1;
int QDesktopWidgetPrivate::primaryScreen = 0;
QVector<QRect> *QDesktopWidgetPrivate::rects = 0;
QVector<QRect> *QDesktopWidgetPrivate::workrects = 0;
+QVector<QWidget *> *QDesktopWidgetPrivate::screens = 0;
int QDesktopWidgetPrivate::refcount = 0;
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+MDisplayControl *QDesktopWidgetPrivate::displayControl = 0;
+#endif
QDesktopWidgetPrivate::QDesktopWidgetPrivate()
{
@@ -88,25 +119,55 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
- Q_UNUSED(that);
-// int screenCount=0;
-
- // ### TODO: Implement proper multi-display support
- QDesktopWidgetPrivate::screenCount = 1;
-// if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
-// QDesktopWidgetPrivate::screenCount = screenCount;
-// else
-// QDesktopWidgetPrivate::screenCount = 0;
+ // Note that on S^3 devices the screen count retrieved via RWsSession
+ // will always be 2 but the width and height for screen number 1 will
+ // be 0 as long as TV-out is not connected.
+ //
+ // On the other hand a valid size for screen 1 will be reported even
+ // after the cable is disconnected. In order to overcome this, we use
+ // MDisplayControl::NumberOfResolutions() to check if the display is
+ // valid or not.
+
+ screenCount = S60->screenCount();
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ if (displayControl) {
+ if (displayControl->NumberOfResolutions() < 1)
+ screenCount = 1;
+ }
+#endif
+ if (screenCount < 1) {
+ qWarning("No screen available");
+ screenCount = 1;
+ }
rects = new QVector<QRect>();
workrects = new QVector<QRect>();
-
- rects->resize(QDesktopWidgetPrivate::screenCount);
- workrects->resize(QDesktopWidgetPrivate::screenCount);
-
- (*rects)[0].setRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels);
- QRect wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
- (*workrects)[0].setRect(wr.x(), wr.y(), wr.width(), wr.height());
+ screens = new QVector<QWidget *>();
+
+ rects->resize(screenCount);
+ workrects->resize(screenCount);
+ screens->resize(screenCount);
+
+ for (int i = 0; i < screenCount; ++i) {
+ // All screens will have a position of (0, 0) as there is no true virtual desktop
+ // or pointer event support for multiple screens on Symbian.
+ QRect r(0, 0,
+ S60->screenWidthInPixelsForScreen[i], S60->screenHeightInPixelsForScreen[i]);
+ // Stop here if empty and ignore this screen.
+ if (r.isEmpty()) {
+ screenCount = i;
+ break;
+ }
+ (*rects)[i] = r;
+ QRect wr;
+ if (i == 0)
+ wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+ else
+ wr = rects->at(i);
+ (*workrects)[i].setRect(wr.x(), wr.y(), wr.width(), wr.height());
+ (*screens)[i] = 0;
+ }
+ (*screens)[0] = that;
}
void QDesktopWidgetPrivate::cleanup()
@@ -115,6 +176,29 @@ void QDesktopWidgetPrivate::cleanup()
rects = 0;
delete workrects;
workrects = 0;
+ if (screens) {
+ // First item is the QDesktopWidget so skip it.
+ for (int i = 1; i < screens->count(); ++i)
+ delete screens->at(i);
+ }
+ delete screens;
+ screens = 0;
+}
+
+void QDesktopWidgetPrivate::init_sys()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ if (S60->screenCount() > 1) {
+ CWsScreenDevice *dev = S60->screenDevice(1);
+ if (dev) {
+ displayControl = static_cast<MDisplayControl *>(
+ dev->GetInterface(MDisplayControl::ETypeId));
+ if (displayControl) {
+ displayControl->EnableDisplayChangeEvents(ETrue);
+ }
+ }
+ }
+#endif
}
@@ -122,6 +206,7 @@ QDesktopWidget::QDesktopWidget()
: QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
{
setObjectName(QLatin1String("desktop"));
+ QDesktopWidgetPrivate::init_sys();
QDesktopWidgetPrivate::init(this);
}
@@ -131,7 +216,7 @@ QDesktopWidget::~QDesktopWidget()
bool QDesktopWidget::isVirtualDesktop() const
{
- return true;
+ return false;
}
int QDesktopWidget::primaryScreen() const
@@ -145,9 +230,23 @@ int QDesktopWidget::numScreens() const
return QDesktopWidgetPrivate::screenCount;
}
-QWidget *QDesktopWidget::screen(int /* screen */)
+static inline QWidget *newSingleDesktopWidget(int screen)
{
- return this;
+ qt_symbian_create_desktop_on_screen = screen;
+ QWidget *w = new QSingleDesktopWidget;
+ qt_symbian_create_desktop_on_screen = -1;
+ return w;
+}
+
+QWidget *QDesktopWidget::screen(int screen)
+{
+ Q_D(QDesktopWidget);
+ if (screen < 0 || screen >= d->screenCount)
+ screen = d->primaryScreen;
+ if (!d->screens->at(screen)
+ || d->screens->at(screen)->windowType() != Qt::Desktop)
+ (*d->screens)[screen] = newSingleDesktopWidget(screen);
+ return (*d->screens)[screen];
}
const QRect QDesktopWidget::availableGeometry(int screen) const
@@ -168,14 +267,19 @@ const QRect QDesktopWidget::screenGeometry(int screen) const
return d->rects->at(screen);
}
-int QDesktopWidget::screenNumber(const QWidget * /* widget */) const
+int QDesktopWidget::screenNumber(const QWidget *widget) const
{
- return QDesktopWidgetPrivate::primaryScreen;
+ Q_D(const QDesktopWidget);
+ return widget
+ ? S60->screenNumberForWidget(widget)
+ : d->primaryScreen;
}
-int QDesktopWidget::screenNumber(const QPoint & /* point */) const
+int QDesktopWidget::screenNumber(const QPoint &point) const
{
- return QDesktopWidgetPrivate::primaryScreen;
+ Q_UNUSED(point);
+ Q_D(const QDesktopWidget);
+ return d->primaryScreen;
}
void QDesktopWidget::resizeEvent(QResizeEvent *)
@@ -203,6 +307,10 @@ void QDesktopWidget::resizeEvent(QResizeEvent *)
if (oldrect != newrect)
emit workAreaResized(j);
}
+
+ if (oldscreencount != d->screenCount) {
+ emit screenCountChanged(d->screenCount);
+ }
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 1b26933..204efe9 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -50,6 +50,10 @@
#include "private/qsoftkeymanager_s60_p.h"
#endif
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+#include "private/qt_s60_p.h"
+#endif
+
#ifndef QT_NO_SOFTKEYMANAGER
QT_BEGIN_NAMESPACE
@@ -101,6 +105,30 @@ QSoftKeyManager::QSoftKeyManager() :
QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *actionWidget)
{
QAction *action = new QAction(standardSoftKeyText(standardKey), actionWidget);
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+ int key = 0;
+ switch (standardKey) {
+ case OkSoftKey:
+ key = EAknSoftkeyOk;
+ break;
+ case SelectSoftKey:
+ key = EAknSoftkeySelect;
+ break;
+ case DoneSoftKey:
+ key = EAknSoftkeyDone;
+ break;
+ case MenuSoftKey:
+ key = EAknSoftkeyOptions;
+ break;
+ case CancelSoftKey:
+ key = EAknSoftkeyCancel;
+ break;
+ default:
+ break;
+ };
+ if (key != 0)
+ QSoftKeyManager::instance()->d_func()->softKeyCommandActions.insert(action, key);
+#endif
QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
switch (standardKey) {
case MenuSoftKey: // FALL-THROUGH
@@ -143,6 +171,9 @@ void QSoftKeyManager::cleanupHash(QObject *obj)
Q_D(QSoftKeyManager);
QAction *action = qobject_cast<QAction*>(obj);
d->keyedActions.remove(action);
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+ d->softKeyCommandActions.remove(action);
+#endif
}
void QSoftKeyManager::sendKeyEvent()
diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h
index 27d8ee9..02ae697 100644
--- a/src/gui/kernel/qsoftkeymanager_common_p.h
+++ b/src/gui/kernel/qsoftkeymanager_common_p.h
@@ -72,6 +72,9 @@ protected:
QMultiHash<int, QAction*> requestedSoftKeyActions;
QWidget *initialSoftKeySource;
bool pendingUpdate;
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+ QHash<QAction*, int> softKeyCommandActions;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
index 3496297..79ed91a 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -113,12 +113,20 @@ void QSoftKeyManagerPrivateS60::ensureCbaVisibilityAndResponsiviness(CEikButtonG
void QSoftKeyManagerPrivateS60::clearSoftkeys(CEikButtonGroupContainer &cba)
{
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+ QT_TRAP_THROWING(
+ //EAknSoftkeyEmpty is used, because using -1 adds softkeys without actions on Symbian3
+ cba.SetCommandL(0, EAknSoftkeyEmpty, KNullDesC);
+ cba.SetCommandL(2, EAknSoftkeyEmpty, KNullDesC);
+ );
+#else
QT_TRAP_THROWING(
//Using -1 instead of EAknSoftkeyEmpty to avoid flickering.
cba.SetCommandL(0, -1, KNullDesC);
// TODO: Should we clear also middle SK?
cba.SetCommandL(2, -1, KNullDesC);
);
+#endif
realSoftKeyActions.clear();
}
@@ -290,6 +298,10 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba,
QString text = softkeyText(*action);
TPtrC nativeText = qt_QString2TPtrC(text);
int command = S60_COMMAND_START + position;
+#ifdef SYMBIAN_VERSION_SYMBIAN3
+ if (softKeyCommandActions.contains(action))
+ command = softKeyCommandActions.value(action);
+#endif
setNativeSoftkey(cba, position, command, nativeText);
const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action);
cba.DimCommand(command, dimmed);
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 3820bfc..20c1ddb 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1391,6 +1391,7 @@ void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayI
void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse)
{
+ QMacCocoaAutoReleasePool pool;
OSMenuRef menu = static_cast<OSMenuRef>(theMenu);
if (collapse) {
bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 40697bf..8aba53a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -64,6 +64,7 @@
#include "qapplication.h"
#include "qelapsedtimer.h"
#include "QtCore/qthreadstorage.h"
+#include "qwidget_p.h"
#include <w32std.h>
#include <coecntrl.h>
#include <eikenv.h>
@@ -76,6 +77,10 @@
#include <akncontext.h> // CAknContextPane
#include <eikspane.h> // CEikStatusPane
#include <AknPopupFader.h> // MAknFadedComponent and TAknPopupFader
+#include <gfxtranseffect/gfxtranseffect.h> // BeginFullScreen
+#ifdef QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
+#include <akntranseffect.h> // BeginFullScreen
+#endif
#endif
QT_BEGIN_NAMESPACE
@@ -84,6 +89,11 @@ QT_BEGIN_NAMESPACE
// system events seems to start with 0x10
const TInt KInternalStatusPaneChange = 0x50000000;
+// For BeginFullScreen().
+const TUint KQtAppExitFlag = 0x400;
+
+static const int qt_symbian_max_screens = 4;
+
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
@@ -142,7 +152,10 @@ public:
int avkonComponentsSupportTransparency : 1;
int menuBeingConstructed : 1;
int orientationSet : 1;
+ int partial_keyboard : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
+ QPointer<QWidget> splitViewLastWidget;
+
static CEikButtonGroupContainer *cba;
enum ScanCodeState {
@@ -154,8 +167,14 @@ public:
static inline void updateScreenSize();
inline RWsSession& wsSession();
+ static inline int screenCount();
static inline RWindowGroup& windowGroup();
+ static inline RWindowGroup& windowGroup(const QWidget *widget);
+ static inline RWindowGroup& windowGroup(int screenNumber);
inline CWsScreenDevice* screenDevice();
+ inline CWsScreenDevice* screenDevice(const QWidget *widget);
+ inline CWsScreenDevice* screenDevice(int screenNumber);
+ static inline int screenNumberForWidget(const QWidget *widget);
static inline CCoeAppUi* appUi();
static inline CEikMenuBar* menuBar();
#ifdef Q_WS_S60
@@ -166,12 +185,24 @@ public:
static inline CEikButtonGroupContainer* buttonGroupContainer();
static inline void setButtonGroupContainer(CEikButtonGroupContainer* newCba);
static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible);
+ static bool setRecursiveDecorationsVisibility(QWidget *window, Qt::WindowStates newState);
#endif
static void controlVisibilityChanged(CCoeControl *control, bool visible);
#ifdef Q_OS_SYMBIAN
TTrapHandler *s60InstalledTrapHandler;
#endif
+
+ int screenWidthInPixelsForScreen[qt_symbian_max_screens];
+ int screenHeightInPixelsForScreen[qt_symbian_max_screens];
+ int screenWidthInTwipsForScreen[qt_symbian_max_screens];
+ int screenHeightInTwipsForScreen[qt_symbian_max_screens];
+
+ int nativeScreenWidthInPixels;
+ int nativeScreenHeightInPixels;
+
+ int beginFullScreenCalled : 1;
+ int endFullScreenCalled : 1;
};
Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data();
@@ -216,6 +247,10 @@ public:
bool isControlActive();
+ void ensureFixNativeOrientation();
+ QPoint translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const;
+ TRect translateRectForFixedNativeOrientation(const TRect &controlRect) const;
+
#ifdef Q_WS_S60
void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
void HandleStatusPaneSizeChange();
@@ -234,6 +269,9 @@ protected:
void PositionChanged();
void FocusChanged(TDrawNow aDrawNow);
+protected:
+ void qwidgetResize_helper(const QSize &newSize);
+
private:
void HandlePointerEvent(const TPointerEvent& aPointerEvent);
TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
@@ -252,6 +290,7 @@ private:
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
#endif
+ bool isSplitViewWidget(QWidget *widget);
public:
void handleClientAreaChange();
@@ -270,6 +309,9 @@ private:
// Fader object used to fade everything except this menu and the CBA.
TAknPopupFader popupFader;
#endif
+
+ bool m_inExternalScreenOverride : 1;
+ bool m_lastStatusPaneVisibility : 1;
};
inline QS60Data::QS60Data()
@@ -297,18 +339,23 @@ inline QS60Data::QS60Data()
avkonComponentsSupportTransparency(0),
menuBeingConstructed(0),
orientationSet(0),
+ partial_keyboard(0),
s60ApplicationFactory(0)
#ifdef Q_OS_SYMBIAN
,s60InstalledTrapHandler(0)
#endif
+ ,beginFullScreenCalled(0),
+ endFullScreenCalled(0)
{
}
inline void QS60Data::updateScreenSize()
{
+ CWsScreenDevice *dev = S60->screenDevice();
+ int screenModeCount = dev->NumScreenModes();
+ int mode = dev->CurrentScreenMode();
TPixelsTwipsAndRotation params;
- int mode = S60->screenDevice()->CurrentScreenMode();
- S60->screenDevice()->GetScreenModeSizeAndRotation(mode, params);
+ dev->GetScreenModeSizeAndRotation(mode, params);
S60->screenWidthInPixels = params.iPixelSize.iWidth;
S60->screenHeightInPixels = params.iPixelSize.iHeight;
S60->screenWidthInTwips = params.iTwipsSize.iWidth;
@@ -320,6 +367,29 @@ inline void QS60Data::updateScreenSize()
S60->defaultDpiY = S60->screenHeightInPixels / inches;
inches = S60->screenWidthInTwips / (TReal)KTwipsPerInch;
S60->defaultDpiX = S60->screenWidthInPixels / inches;
+
+ int screens = S60->screenCount();
+ for (int i = 0; i < screens; ++i) {
+ CWsScreenDevice *dev = S60->screenDevice(i);
+ mode = dev->CurrentScreenMode();
+ dev->GetScreenModeSizeAndRotation(mode, params);
+ S60->screenWidthInPixelsForScreen[i] = params.iPixelSize.iWidth;
+ S60->screenHeightInPixelsForScreen[i] = params.iPixelSize.iHeight;
+ S60->screenWidthInTwipsForScreen[i] = params.iTwipsSize.iWidth;
+ S60->screenHeightInTwipsForScreen[i] = params.iTwipsSize.iHeight;
+ }
+
+ // Look for a screen mode with rotation 0
+ // in order to decide what the native orientation is.
+ for (mode = 0; mode < screenModeCount; ++mode) {
+ TPixelsAndRotation sizeAndRotation;
+ dev->GetScreenModeSizeAndRotation(mode, sizeAndRotation);
+ if (sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal) {
+ S60->nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth;
+ S60->nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight;
+ break;
+ }
+ }
}
inline RWsSession& QS60Data::wsSession()
@@ -330,11 +400,38 @@ inline RWsSession& QS60Data::wsSession()
return tls.localData()->wsSession;
}
+inline int QS60Data::screenCount()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ return qMin(env->WsSession().NumberOfScreens(), qt_symbian_max_screens);
+ }
+#endif
+ return 1;
+}
+
inline RWindowGroup& QS60Data::windowGroup()
{
return CCoeEnv::Static()->RootWin();
}
+inline RWindowGroup& QS60Data::windowGroup(const QWidget *widget)
+{
+ return windowGroup(screenNumberForWidget(widget));
+}
+
+inline RWindowGroup& QS60Data::windowGroup(int screenNumber)
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ RWindowGroup *wg = CCoeEnv::Static()->RootWin(screenNumber);
+ return wg ? *wg : windowGroup();
+#else
+ Q_UNUSED(screenNumber);
+ return windowGroup();
+#endif
+}
+
inline CWsScreenDevice* QS60Data::screenDevice()
{
if(!tls.hasLocalData()) {
@@ -343,6 +440,36 @@ inline CWsScreenDevice* QS60Data::screenDevice()
return tls.localData()->screenDevice;
}
+inline CWsScreenDevice* QS60Data::screenDevice(const QWidget *widget)
+{
+ return screenDevice(screenNumberForWidget(widget));
+}
+
+inline CWsScreenDevice* QS60Data::screenDevice(int screenNumber)
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ CWsScreenDevice *dev = env->ScreenDevice(screenNumber);
+ return dev ? dev : screenDevice();
+ } else {
+ return screenDevice();
+ }
+#else
+ return screenDevice();
+#endif
+}
+
+inline int QS60Data::screenNumberForWidget(const QWidget *widget)
+{
+ if (!widget)
+ return 0;
+ const QWidget *w = widget;
+ while (w->parentWidget())
+ w = w->parentWidget();
+ return qt_widget_private(const_cast<QWidget *>(w))->symbianScreenNumber;
+}
+
inline CCoeAppUi* QS60Data::appUi()
{
return CCoeEnv::Static()-> AppUi();
@@ -450,6 +577,49 @@ void qt_symbian_set_cursor_visible(bool visible);
bool qt_symbian_is_cursor_visible();
#endif
+static inline bool qt_beginFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ // Only for post-S^3. On earlier versions the system transition effects
+ // may not be able to capture the non-Avkon content, leading to confusing
+ // looking effects, so just skip the whole thing.
+ if (S60->beginFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return false;
+ S60->beginFullScreenCalled = true;
+ // For Avkon apps the app-exit effect is triggered from CAknAppUi::PrepareToExit().
+ // That is good for Avkon apps, but in case of Qt the RWindows are destroyed earlier.
+ // Therefore we call BeginFullScreen() ourselves.
+ GfxTransEffect::BeginFullScreen(AknTransEffect::EApplicationExit,
+ TRect(0, 0, 0, 0),
+ AknTransEffect::EParameterType,
+ AknTransEffect::GfxTransParam(S60->uid,
+ AknTransEffect::TParameter::EAvkonCheck | KQtAppExitFlag));
+ return true;
+#else
+ return false;
+#endif
+}
+
+static inline void qt_abortFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ if (!S60->beginFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return;
+ GfxTransEffect::AbortFullScreen();
+ S60->beginFullScreenCalled = S60->endFullScreenCalled = false;
+#endif
+}
+
+static inline void qt_endFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ if (S60->endFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return;
+ S60->endFullScreenCalled = true;
+ GfxTransEffect::EndFullScreen();
+#endif
+}
+
QT_END_NAMESPACE
#endif // QT_S60_P_H
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 7065e85..ac35d42 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -304,6 +304,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
, hasAlienChildren(0)
, window_event(0)
, qd_hd(0)
+#elif defined(Q_OS_SYMBIAN)
+ , symbianScreenNumber(0)
+ , fixNativeOrientationCalled(false)
#endif
{
if (!qApp) {
@@ -595,8 +598,7 @@ void QWidget::setAutoFillBackground(bool enabled)
\brief The QWidget class is the base class of all user interface objects.
\ingroup basicwidgets
-
-
+
The widget is the atom of the user interface: it receives mouse, keyboard
and other events from the window system, and paints a representation of
itself on the screen. Every widget is rectangular, and they are sorted in a
@@ -1284,6 +1286,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
// programmer specified desktop widget
xinfo = desktopWidget->d_func()->xinfo;
}
+#elif defined(Q_OS_SYMBIAN)
+ if (desktopWidget) {
+ symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
+ }
#else
Q_UNUSED(desktopWidget);
#endif
@@ -1320,8 +1326,8 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
//give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
#ifdef Q_OS_SYMBIAN
if (isGLWidget) {
- // Don't waste GPU mem for unnecessary large egl surface
- data.crect = QRect(0,0,2,2);
+ // Don't waste GPU mem for unnecessary large egl surface until resized by application
+ data.crect = QRect(0,0,1,1);
} else {
data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640);
}
@@ -10860,6 +10866,9 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation));
S60->orientationSet = true;
+ QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId());
+ if (window)
+ window->ensureFixNativeOrientation();
#endif
break;
}
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 7e5173f..8784ffd 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2794,6 +2794,11 @@ void QWidgetPrivate::transferChildren()
#ifdef QT_MAC_USE_COCOA
void QWidgetPrivate::setSubWindowStacking(bool set)
{
+ // After hitting too many unforeseen bugs trying to put Qt on top of the cocoa child
+ // window API, we have decided to revert this behaviour as much as we can. We
+ // therefore now only allow child windows to exist for children of modal dialogs.
+ static bool use_behaviour_qt473 = !qgetenv("QT_MAC_USE_CHILDWINDOWS").isEmpty();
+
// This will set/remove a visual relationship between parent and child on screen.
// The reason for doing this is to ensure that a child always stacks infront of
// its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has
@@ -2822,7 +2827,10 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) {
if (set) {
Qt::WindowType ptype = parent->window()->windowType();
- if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) {
+ if ([pwin isVisible]
+ && (ptype == Qt::Window || ptype == Qt::Dialog)
+ && ![qwin parentWindow]
+ && (use_behaviour_qt473 || parent->windowModality() == Qt::ApplicationModal)) {
NSInteger level = [qwin level];
[pwin addChildWindow:qwin ordered:NSWindowAbove];
if ([qwin level] < level)
@@ -2834,6 +2842,10 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
}
}
+ // Only set-up child windows for q if q is modal:
+ if (set && !use_behaviour_qt473 && q->windowModality() != Qt::ApplicationModal)
+ return;
+
QObjectList widgets = q->children();
for (int i=0; i<widgets.size(); ++i) {
QWidget *child = qobject_cast<QWidget *>(widgets.at(i));
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 9f6ba6f..377e3a7 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -315,6 +315,11 @@ struct QWExtra {
*/
ZeroFill,
+ /**
+ * Blit backing store, propagating alpha channel into the framebuffer.
+ */
+ BlitWriteAlpha,
+
Default = Blit
};
@@ -877,6 +882,8 @@ public:
#elif defined(Q_OS_SYMBIAN) // <--------------------------------------------------------- SYMBIAN
static QWidget *mouseGrabber;
static QWidget *keyboardGrabber;
+ int symbianScreenNumber; // only valid for desktop widget and top-levels
+ bool fixNativeOrientationCalled;
void s60UpdateIsOpaque();
void reparentChildren();
void registerTouchWindow();
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index af9ae47..d55e1ad 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -84,6 +84,8 @@ QWidget *QWidgetPrivate::mouseGrabber = 0;
QWidget *QWidgetPrivate::keyboardGrabber = 0;
CEikButtonGroupContainer *QS60Data::cba = 0;
+int qt_symbian_create_desktop_on_screen = -1;
+
static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
{
if ( a.count() != b.count())
@@ -276,6 +278,8 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h)));
topData()->normalGeometry = data.crect;
}
+ QSymbianControl *window = static_cast<QSymbianControl *>(q->internalWinId());
+ window->ensureFixNativeOrientation();
} else {
data.crect.setRect(x, y, w, h);
@@ -349,12 +353,18 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
int sh = clientRect.Height();
if (desktop) {
- TSize screenSize = S60->screenDevice()->SizeInPixels();
+ symbianScreenNumber = qMax(qt_symbian_create_desktop_on_screen, 0);
+ TSize screenSize = S60->screenDevice(symbianScreenNumber)->SizeInPixels();
data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight);
q->setAttribute(Qt::WA_DontShowOnScreen);
} else if (topLevel && !q->testAttribute(Qt::WA_Resized)){
int width = sw;
int height = sh;
+ if (symbianScreenNumber > 0) {
+ TSize screenSize = S60->screenDevice(symbianScreenNumber)->SizeInPixels();
+ width = screenSize.iWidth;
+ height = screenSize.iHeight;
+ }
if (extra) {
width = qMax(qMin(width, extra->maxw), extra->minw);
height = qMax(qMin(height, extra->maxh), extra->minh);
@@ -640,7 +650,7 @@ void QWidgetPrivate::raise_sys()
// If toplevel widget, raise app to foreground
if (q->isWindow())
- S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), 0);
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup(q).Identifier(), 0);
}
}
@@ -652,7 +662,7 @@ void QWidgetPrivate::lower_sys()
if (q->internalWinId()) {
// If toplevel widget, lower app to background
if (q->isWindow())
- S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), -1);
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup(q).Identifier(), -1);
else
q->internalWinId()->DrawableWindow()->SetOrdinalPosition(-1);
}
@@ -722,6 +732,11 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
{
Q_Q(QWidget);
+ if (parent && parent->windowType() == Qt::Desktop) {
+ symbianScreenNumber = qt_widget_private(parent)->symbianScreenNumber;
+ parent = 0;
+ }
+
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
@@ -792,36 +807,45 @@ void QWidgetPrivate::s60UpdateIsOpaque()
{
Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
+ if (!q->testAttribute(Qt::WA_WState_Created))
+ return;
+
+ const bool writeAlpha = extraData()->nativePaintMode == QWExtra::BlitWriteAlpha;
+ if (!q->testAttribute(Qt::WA_TranslucentBackground) && !writeAlpha)
return;
+ const bool requireAlphaChannel = !isOpaque || writeAlpha;
createTLExtra();
RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
- window->SetSurfaceTransparency(!isOpaque);
- extra->topextra->nativeWindowTransparencyEnabled = !isOpaque;
-#else
- if (!isOpaque) {
+ if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
+ window->SetSurfaceTransparency(!isOpaque);
+ extra->topextra->nativeWindowTransparencyEnabled = !isOpaque;
+ return;
+ }
+#endif
+ if (requireAlphaChannel) {
const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
if (window->SetTransparencyAlphaChannel() == KErrNone) {
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
extra->topextra->nativeWindowTransparencyEnabled = 1;
-
- if (extra->topextra->backingStore.data() &&
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")) {
+ if (extra->topextra->backingStore.data() && (
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl"))) {
// Semi-transparent EGL surfaces aren't supported. We need to
// recreate backing store to get translucent surface (raster surface).
extra->topextra->backingStore.create(q);
extra->topextra->backingStore.registerWidget(q);
+ // FixNativeOrientation() will not work without an EGL surface.
+ q->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
}
}
} else if (extra->topextra->nativeWindowTransparencyEnabled) {
window->SetTransparentRegion(TRegionFix<1>());
extra->topextra->nativeWindowTransparencyEnabled = 0;
}
-#endif
}
void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
@@ -1037,7 +1061,7 @@ int QWidget::metric(PaintDeviceMetric m) const
} else if (m == PdmHeight) {
val = data->crect.height();
} else {
- CWsScreenDevice *scr = S60->screenDevice();
+ CWsScreenDevice *scr = S60->screenDevice(this);
switch(m) {
case PdmDpiX:
case PdmPhysicalDpiX:
@@ -1184,17 +1208,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
}
#ifdef Q_WS_S60
- bool decorationsVisible(false);
- if (!parentWidget()) { // Only top level native windows have control over cba/status pane
- // Hide window decoration when switching to fullscreen / minimized otherwise show decoration.
- // 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 unnecessary redraws
- decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
- const bool statusPaneVisibility = decorationsVisible;
- const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested));
- S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
- }
+ // 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 unnecessary redraws
+ bool decorationsVisible = S60->setRecursiveDecorationsVisibility(this, newstate);
#endif // Q_WS_S60
// Ensure the initial size is valid, since we store it as normalGeometry below.
@@ -1207,7 +1224,16 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) {
setAttribute(Qt::WA_OutsideWSRange, false);
- window->SetExtentToWholeScreen();
+ if (d->symbianScreenNumber > 0) {
+ int w = S60->screenWidthInPixelsForScreen[d->symbianScreenNumber];
+ int h = S60->screenHeightInPixelsForScreen[d->symbianScreenNumber];
+ if (w <= 0 || h <= 0)
+ window->SetExtentToWholeScreen();
+ else
+ window->SetExtent(TPoint(0, 0), TSize(w, h));
+ } else {
+ window->SetExtentToWholeScreen();
+ }
} else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) {
setAttribute(Qt::WA_OutsideWSRange, false);
TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this));
@@ -1244,6 +1270,12 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (newstate & Qt::WindowActive)
activateWindow();
+ if (isWindow()) {
+ // Now that the new state is set, fix the display memory layout, if needed.
+ QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
+ window->ensureFixNativeOrientation();
+ }
+
QWindowStateChangeEvent e(oldstate);
QApplication::sendEvent(this, &e);
}
@@ -1390,7 +1422,8 @@ void QWidget::activateWindow()
if (tlw->isVisible()) {
window()->createWinId();
QSymbianControl *id = static_cast<QSymbianControl *>(tlw->internalWinId());
- id->setFocusSafely(true);
+ if (!id->IsFocused())
+ id->setFocusSafely(true);
}
}
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 83c58c4..4fcff1d 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -1117,6 +1117,11 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
return;
}
+ // If there's no partial update support we always need
+ // to do a full repaint before flushing
+ if (!windowSurface->hasPartialUpdateSupport())
+ fullUpdatePending = true;
+
// Nothing to repaint.
if (!isDirty()) {
qt_flush(exposedWidget, exposedRegion, windowSurface, tlw, tlwOffset);
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index dc61e34..8f965c2 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -49,6 +49,7 @@
#include "qdebug.h"
#include <QtCore/qcoreapplication.h>
#include "private/qstylehelper_p.h"
+#include <QtCore/qnumeric.h>
QT_BEGIN_NAMESPACE
@@ -1360,13 +1361,14 @@ QGradient::QGradient()
void QGradient::setColorAt(qreal pos, const QColor &color)
{
- if (pos > 1 || pos < 0) {
+ if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
return;
}
int index = 0;
- while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
+ if (!qIsNaN(pos))
+ while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
if (index < m_stops.size() && m_stops.at(index).first == pos)
m_stops[index].second = color;
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 00b103d..debca37 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -327,10 +327,8 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
blend_8_pixels_argb32_on_rgb16_neon(dstBuffer, srcBuffer, const_alpha);
- for (int j = 0; j < tail; ++j) {
+ for (int j = 0; j < tail; ++j)
dst[i + j] = dstBuffer[j];
- src[i + j] = srcBuffer[j];
- }
}
dst = (quint16 *)(((uchar *) dst) + dbpl);
diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp
index 770d947..5112019 100644
--- a/src/gui/painting/qgraphicssystem.cpp
+++ b/src/gui/painting/qgraphicssystem.cpp
@@ -84,4 +84,9 @@ QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin)
return createPixmapData(origin->pixelType());
}
+void QGraphicsSystem::releaseCachedResources()
+{
+ // Do nothing here
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h
index 76e9a8e..80e8959 100644
--- a/src/gui/painting/qgraphicssystem_p.h
+++ b/src/gui/painting/qgraphicssystem_p.h
@@ -72,6 +72,8 @@ public:
//### Remove this & change qpixmap.cpp & qbitmap.cpp once every platform is gaurenteed
// to have a graphics system.
static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type);
+
+ virtual void releaseCachedResources();
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp
index 0294c4b..33652ee 100644
--- a/src/gui/painting/qgraphicssystem_runtime.cpp
+++ b/src/gui/painting/qgraphicssystem_runtime.cpp
@@ -285,6 +285,7 @@ void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion &region,
void QRuntimeWindowSurface::setGeometry(const QRect &rect)
{
+ QWindowSurface::setGeometry(rect);
m_windowSurface->setGeometry(rect);
}
@@ -393,7 +394,10 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
- proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
+ QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget);
+ newWindowSurface->setGeometry(proxy->geometry());
+
+ proxy->m_windowSurface.reset(newWindowSurface);
qt_widget_private(widget)->invalidateBuffer(widget->rect());
}
diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp
index c3aac1b..b07053e 100644
--- a/src/gui/painting/qpaintengine_mac.cpp
+++ b/src/gui/painting/qpaintengine_mac.cpp
@@ -969,7 +969,7 @@ void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, co
return;
bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false;
- CGRect rect = CGRectMake(qRound(r.x()), qRound(r.y()), qRound(r.width()), qRound(r.height()));
+ CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
QCFType<CGImageRef> image;
bool isBitmap = (pm.depth() == 1);
if (isBitmap) {
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 682731a..ba618ea 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3706,6 +3706,13 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,
const bool squareCap = (pen.capStyle() == Qt::SquareCap);
const QVector<qreal> pattern = pen.dashPattern();
+ qreal patternLength = 0;
+ for (int i = 0; i < pattern.size(); ++i)
+ patternLength += pattern.at(i);
+
+ if (patternLength <= 0)
+ return;
+
qreal length = line.length();
Q_ASSERT(length > 0);
while (length > 0) {
diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp
index 1bc7799..ca303be 100644
--- a/src/gui/painting/qpaintengine_s60.cpp
+++ b/src/gui/painting/qpaintengine_s60.cpp
@@ -41,6 +41,7 @@
#include <private/qpaintengine_s60_p.h>
#include <private/qpixmap_s60_p.h>
#include <private/qt_s60_p.h>
+#include <private/qvolatileimage_p.h>
QT_BEGIN_NAMESPACE
@@ -90,7 +91,15 @@ void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
QRasterPaintEngine::drawPixmap(p, pm);
srcData->endDataAccess();
} else {
- QRasterPaintEngine::drawPixmap(p, pm);
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(p, img->imageRef());
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(p, pm);
+ }
}
}
@@ -102,7 +111,15 @@ void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRect
QRasterPaintEngine::drawPixmap(r, pm, sr);
srcData->endDataAccess();
} else {
- QRasterPaintEngine::drawPixmap(r, pm, sr);
+ void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ }
}
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 76ac7db..3735e7c 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -95,10 +95,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
const QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
-static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat);
+Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat);
static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
@@ -5937,9 +5937,9 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
}
d->extended->drawStaticTextItem(item);
- drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions,
- item->numGlyphs, item->fontEngine(), staticText_d->font,
- QTextCharFormat());
+ qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
+ item->numGlyphs, item->fontEngine(), staticText_d->font,
+ QTextCharFormat());
}
if (currentColor != oldPen.color())
setPen(oldPen);
@@ -6383,10 +6383,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setBrush(oldBrush);
}
-static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat)
+Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat)
{
if (!(font.underline() || font.strikeOut() || font.overline()))
return;
@@ -8097,12 +8097,16 @@ start_lengthVariant:
QTextLine line = textLayout.lineAt(i);
qreal advance = line.horizontalAdvance();
- if (tf & Qt::AlignRight)
- xoff = r.width() - advance;
+ xoff = 0;
+ if (tf & Qt::AlignRight) {
+ QTextEngine *eng = textLayout.engine();
+ xoff = r.width() - advance -
+ eng->leadingSpaceWidth(eng->lines[line.lineNumber()]).toReal();
+ }
else if (tf & Qt::AlignHCenter)
- xoff = (r.width() - advance)/2;
+ xoff = (r.width() - advance) / 2;
- line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
+ line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
}
if (restore) {
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 9ef6955..0bb2901 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1690,7 +1690,7 @@ static void qt_painterpath_isect_line(const QPointF &p1,
}
static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
- int *winding)
+ int *winding, int depth = 0)
{
qreal y = pt.y();
qreal x = pt.x();
@@ -1705,7 +1705,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// hit lower limit... This is a rough threshold, but its a
// tradeoff between speed and precision.
const qreal lower_bound = qreal(.001);
- if (bounds.width() < lower_bound && bounds.height() < lower_bound) {
+ if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) {
// We make the assumption here that the curve starts to
// approximate a line after while (i.e. that it doesn't
// change direction drastically during its slope)
@@ -1718,8 +1718,8 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// split curve and try again...
QBezier first_half, second_half;
bezier.split(&first_half, &second_half);
- qt_painterpath_isect_curve(first_half, pt, winding);
- qt_painterpath_isect_curve(second_half, pt, winding);
+ qt_painterpath_isect_curve(first_half, pt, winding, depth + 1);
+ qt_painterpath_isect_curve(second_half, pt, winding, depth + 1);
}
}
@@ -1863,39 +1863,39 @@ static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y
return false;
}
-static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2)
+static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2, int depth = 0)
{
QRectF bounds = bezier.bounds();
if (y >= bounds.top() && y < bounds.bottom()
&& bounds.right() >= x1 && bounds.left() < x2) {
const qreal lower_bound = qreal(.01);
- if (bounds.width() < lower_bound && bounds.height() < lower_bound)
+ if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound)
return true;
QBezier first_half, second_half;
bezier.split(&first_half, &second_half);
- if (qt_isect_curve_horizontal(first_half, y, x1, x2)
- || qt_isect_curve_horizontal(second_half, y, x1, x2))
+ if (qt_isect_curve_horizontal(first_half, y, x1, x2, depth + 1)
+ || qt_isect_curve_horizontal(second_half, y, x1, x2, depth + 1))
return true;
}
return false;
}
-static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2)
+static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2, int depth = 0)
{
QRectF bounds = bezier.bounds();
if (x >= bounds.left() && x < bounds.right()
&& bounds.bottom() >= y1 && bounds.top() < y2) {
const qreal lower_bound = qreal(.01);
- if (bounds.width() < lower_bound && bounds.height() < lower_bound)
+ if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound)
return true;
QBezier first_half, second_half;
bezier.split(&first_half, &second_half);
- if (qt_isect_curve_vertical(first_half, x, y1, y2)
- || qt_isect_curve_vertical(second_half, x, y1, y2))
+ if (qt_isect_curve_vertical(first_half, x, y1, y2, depth + 1)
+ || qt_isect_curve_vertical(second_half, x, y1, y2, depth + 1))
return true;
}
return false;
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 9f371a8..cb53ea0 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -63,7 +63,6 @@ struct QS60WindowSurfacePrivate
TDisplayMode displayMode(bool opaque)
{
-
TDisplayMode mode = S60->screenDevice()->DisplayMode();
if (opaque) {
mode = EColor16MU;
@@ -76,10 +75,18 @@ TDisplayMode displayMode(bool opaque)
return mode;
}
+bool blitWriteAlpha(QWidgetPrivate *widgetPrivate)
+{
+ QWExtra *extra = widgetPrivate->extraData();
+ return extra ? extra->nativePaintMode == QWExtra::BlitWriteAlpha : false;
+}
+
QS60WindowSurface::QS60WindowSurface(QWidget* widget)
: QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate)
{
- TDisplayMode mode = displayMode(qt_widget_private(widget)->isOpaque);
+ QWidgetPrivate *widgetPrivate = qt_widget_private(widget);
+ const bool opaque = widgetPrivate->isOpaque && !blitWriteAlpha(widgetPrivate);
+ TDisplayMode mode = displayMode(opaque);
// We create empty CFbsBitmap here -> it will be resized in setGeometry
CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
@@ -123,7 +130,8 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
S60->wsSession().Finish();
#endif
- if (!qt_widget_private(window())->isOpaque) {
+ QWidgetPrivate *windowPrivate = qt_widget_private(window());
+ if (!windowPrivate->isOpaque || blitWriteAlpha(windowPrivate)) {
QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
TDisplayMode mode = displayMode(false);
@@ -132,12 +140,14 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
pixmapData->beginDataAccess();
- QPainter p(&pixmapData->image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
+ if (!windowPrivate->isOpaque) {
+ QPainter p(&pixmapData->image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = rgn.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
}
pixmapData->endDataAccess();
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index b5b8b81..4842bc5 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -61,6 +61,7 @@
//Animated wallpapers in Qt applications are not supported.
const TInt KAknDisableAnimationBackground = 0x02000000;
+const TInt KAknSingleClickCompatible = 0x01000000;
QT_BEGIN_NAMESPACE
@@ -117,8 +118,12 @@ void QS60MainAppUi::ConstructL()
// After 5th Edition S60, native side supports animated wallpapers.
// However, there is no support for that feature on Qt side, so indicate to
// native UI framework that this application will not support background animations.
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- flags |= KAknDisableAnimationBackground;
+
+ // Also, add support for single touch for post 5th edition platforms.
+ // This has only impact when launching native dialogs/menus from inside QApplication.
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ flags |= (KAknDisableAnimationBackground | KAknSingleClickCompatible);
+ }
#endif
BaseConstructL(flags);
}
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 38a4b7c..9958316 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -72,6 +72,7 @@
#include "qcheckbox.h"
#include "qdesktopwidget.h"
#include "qprogressbar.h"
+#include "qlabel.h"
#include "private/qtoolbarextension_p.h"
#include "private/qcombobox_p.h"
@@ -107,8 +108,8 @@ const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
{5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106},
{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106},
-{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
-{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
+{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106},
{9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184}
// *** End of generated data ***
@@ -118,6 +119,7 @@ const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0];
// theme background texture
QPixmap *QS60StylePrivate::m_background = 0;
+QPixmap *QS60StylePrivate::m_placeHolderTexture = 0;
// theme palette
QPalette *QS60StylePrivate::m_themePalette = 0;
@@ -155,6 +157,10 @@ const double KTabFontMul = 0.72;
QS60StylePrivate::~QS60StylePrivate()
{
clearCaches(); //deletes also background image
+ if (m_placeHolderTexture) {
+ delete m_placeHolderTexture;
+ m_placeHolderTexture = 0;
+ }
deleteThemePalette();
#ifdef Q_WS_S60
removeAnimations();
@@ -505,7 +511,10 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
{
Q_UNUSED(app)
QPalette applicationPalette = QApplication::palette();
- applicationPalette.setBrush(QPalette::Window, backgroundTexture());
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ applicationPalette.setBrush(QPalette::Window, placeHolderTexture());
setThemePalette(&applicationPalette);
}
@@ -630,25 +639,6 @@ QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size
return result;
}
-void QS60StylePrivate::refreshUI()
-{
- QList<QWidget *> widgets = QApplication::allWidgets();
-
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *widget = widgets.at(i);
- if (widget == 0)
- continue;
-
- if (widget->style()) {
- widget->style()->polish(widget);
- QEvent event(QEvent::StyleChange);
- qApp->sendEvent(widget, &event);
- }
- widget->update();
- widget->updateGeometry();
- }
-}
-
void QS60StylePrivate::setFont(QWidget *widget) const
{
QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined;
@@ -678,7 +668,7 @@ void QS60StylePrivate::setFont(QWidget *widget) const
}
}
-void QS60StylePrivate::setThemePalette(QWidget *widget) const
+void QS60StylePrivate::setThemePalette(QWidget *widget)
{
if(!widget)
return;
@@ -694,6 +684,13 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const
if (header->viewport())
header->viewport()->setPalette(widgetPalette);
QApplication::setPalette(widgetPalette, "QHeaderView");
+ } else if (qobject_cast<QLabel *>(widget)) {
+ if (widget->window() && widget->window()->windowType() == Qt::Dialog) {
+ QPalette widgetPalette = widget->palette();
+ widgetPalette.setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 19, 0));
+ widget->setPalette(widgetPalette);
+ }
}
}
@@ -719,8 +716,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker());
palette->setColor(QPalette::Highlight,
s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0));
- // set background image as a texture brush
- palette->setBrush(QPalette::Window, backgroundTexture());
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ palette->setBrush(QPalette::Window, placeHolderTexture());
// set as transparent so that styled full screen theme background is visible
palette->setBrush(QPalette::Base, Qt::transparent);
// set button color based on pixel colors
@@ -761,7 +760,7 @@ void QS60StylePrivate::storeThemePalette(QPalette *palette)
}
// set widget specific palettes
-void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
+void QS60StylePrivate::setThemePaletteHash(QPalette *palette)
{
if (!palette)
return;
@@ -966,6 +965,17 @@ bool QS60StylePrivate::isWidgetPressed(const QWidget *widget)
return (widget && widget == m_pressedWidget);
}
+// Generates 1*1 white pixmap as a placeholder for real texture.
+// The actual theme texture is drawn in qt_s60_fill_background().
+QPixmap QS60StylePrivate::placeHolderTexture()
+{
+ if (!m_placeHolderTexture) {
+ m_placeHolderTexture = new QPixmap(1,1);
+ m_placeHolderTexture->fill(Qt::green);
+ }
+ return *m_placeHolderTexture;
+}
+
/*!
\class QS60Style
\brief The QS60Style class provides a look and feel suitable for applications on S60.
@@ -1551,8 +1561,10 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
const int borderThickness =
QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- const int tabOverlap =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
+
const bool usesScrollButtons =
(widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
const int roomForScrollButton =
@@ -1591,9 +1603,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionTabV3 optionTab = *tab;
QRect tr = optionTab.rect;
const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
- const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- const int tabOverlap =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
const bool usesScrollButtons =
(widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
const int roomForScrollButton =
@@ -1752,16 +1766,26 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionMenuItem optionMenuItem = *menuItem;
bool drawSubMenuIndicator = false;
+ bool drawSeparator = false;
switch(menuItem->menuItemType) {
- case QStyleOptionMenuItem::Scroller:
case QStyleOptionMenuItem::Separator:
- return; // no separators or scrollers in S60 menus
+ drawSeparator = true;
+ break;
+ case QStyleOptionMenuItem::Scroller:
+ return; // no scrollers in S60 menus
case QStyleOptionMenuItem::SubMenu:
drawSubMenuIndicator = true;
break;
default:
break;
}
+ if (drawSeparator) {
+ painter->save();
+ painter->setPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 10, 0));
+ painter->drawLine(optionMenuItem.rect.topLeft(), optionMenuItem.rect.bottomRight());
+ painter->restore();
+ return;
+ }
const bool enabled = optionMenuItem.state & State_Enabled;
const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable;
bool ignoreCheckMark = false;
@@ -1865,20 +1889,26 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
//In Sym^3, native menu items have "lines" between them
if (QS60StylePrivate::isSingleClickUi()) {
- const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0);
- const int spacing = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
- //native platform sets each color byte to same value for "line 16" which just defines alpha for
- //menuitem lines; lets use first byte "red".
- QColor lineColor = optionMenuItem.palette.text().color();
- if (lineColorAlpha.isValid())
- lineColor.setAlpha(lineColorAlpha.red());
- painter->save();
- painter->setPen(lineColor);
-
- const int lineStartX = optionMenuItem.rect.left() + (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) + spacing;
- const int lineEndX = optionMenuItem.rect.right() - (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) - spacing;
- painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom()));
- painter->restore();
+ int diff = widget->geometry().bottom() - optionMenuItem.rect.bottom();
+ if (const QComboBox *cb = qobject_cast<const QComboBox*>(widget))
+ diff = cb->view()->geometry().bottom() - optionMenuItem.rect.bottom();
+
+ // Skip drawing the horizontal line for the last menu item.
+ if (diff > optionMenuItem.rect.height()) {
+ const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0);
+ //native platform sets each color byte to same value for "line 16" which just defines alpha for
+ //menuitem lines; lets use first byte "red".
+ QColor lineColor = optionMenuItem.palette.text().color();
+ if (lineColorAlpha.isValid())
+ lineColor.setAlpha(lineColorAlpha.red());
+ painter->save();
+ painter->setPen(lineColor);
+ const int horizontalMargin = 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ const int lineStartX = optionMenuItem.rect.left() + horizontalMargin;
+ const int lineEndX = optionMenuItem.rect.right() - horizontalMargin;
+ painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom()));
+ painter->restore();
+ }
}
if (!enabled)
painter->restore();
@@ -2273,13 +2303,16 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
#endif //QT_NO_MENU
) {
//Need extra check since dialogs have their own theme background
- if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) &&
- QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window))
- //todo: for combobox listviews, the background should include area for menu scrollers,
- //but this produces drawing issues as we need to turn clipping off.
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags);
- else
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)
+ && QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) {
+ const bool comboMenu = qobject_cast<const QComboBoxListView *>(widget);
+ // Add margin area to the background, to avoid background being cut for first and last item.
+ const int verticalMenuAdjustment = comboMenu ? QS60StylePrivate::pixelMetric(PM_MenuVMargin) : 0;
+ const QRect adjustedMenuRect = option->rect.adjusted(0, -verticalMenuAdjustment, 0, verticalMenuAdjustment);
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, adjustedMenuRect, flags);
+ } else {
commonStyleDraws = true;
+ }
}
break;
case PE_FrameWindow:
@@ -2523,6 +2556,11 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
//without having to define custom pixel metric
metricValue *= 2;
+#if defined(Q_WS_S60)
+ if (metric == PM_TabBarTabOverlap && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_2))
+ metricValue = 0;
+#endif
+
return metricValue;
}
@@ -2547,17 +2585,16 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) && tb->orientation() == Qt::Horizontal;
if (parentCanGrowHorizontally) {
- int visibleButtons = 0;
+ int buttons = 0;
//Make the auto-stretch to happen only for horizontal orientation
if (tb && tb->orientation() == Qt::Horizontal) {
QList<QAction*> actionList = tb->actions();
for (int i = 0; i < actionList.count(); i++) {
- if (actionList.at(i)->isVisible())
- visibleButtons++;
+ buttons++;
}
}
- if (widget->parentWidget() && visibleButtons > 0) {
+ if (widget->parentWidget() && buttons > 0) {
QWidget *w = const_cast<QWidget *>(widget);
int toolBarMaxWidth = 0;
int totalMargin = 0;
@@ -2580,7 +2617,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
toolBarMaxWidth -= totalMargin;
//ensure that buttons are side-by-side and not on top of each other
- const int toolButtonWidth = (toolBarMaxWidth / visibleButtons)
+ const int toolButtonWidth = (toolBarMaxWidth / buttons)
- pixelMetric(QStyle::PM_ToolBarItemSpacing)
- pixelMetric(QStyle::PM_ToolBarItemMargin)
//toolbar frame needs to be reduced again, since QToolBarLayout adds it for each toolbar action
@@ -2613,10 +2650,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz += QSize(2 * f->lineWidth, 4 * f->lineWidth);
break;
case CT_TabBarTab: {
- const QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
- if (naviPaneSize.height() > sz.height())
- sz.setHeight(naviPaneSize.height());
// Adjust beginning tabbar item size, if scrollbuttons are used. This is to ensure that the
// tabbar item content fits, since scrollbuttons are making beginning tabbar item smaller.
int scrollButtonSize = 0;
@@ -2636,17 +2670,18 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_ItemViewItem:
if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- sz = QSize();
+ sz = QSize(menuItem->rect.width() - 2 * pixelMetric(PM_MenuHMargin) - 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 1);
break;
}
}
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
- //native items have small empty areas at the beginning and end of menu item
- sz.setWidth(sz.width() + 2 * pixelMetric(PM_MenuHMargin) + 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth));
- if (QS60StylePrivate::isTouchSupported())
+ if (QS60StylePrivate::isTouchSupported()) {
//Make itemview easier to use in touch devices
+ sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
//QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin) - 8); //QCommonstyle adds 8 to height that this style handles through PM values
+ if (ct == CT_MenuItem)
+ sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values
+ }
break;
#ifndef QT_NO_COMBOBOX
case CT_ComboBox: {
@@ -2998,10 +3033,11 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
ret = QCommonStyle::subElementRect(element, opt, widget);
if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- const int tabOverlapNoBorder =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap);
- const int tabOverlap =
- tabOverlapNoBorder - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
int gain = (tab) ? tabOverlap * tab->count() : 0;
switch (twf->shape) {
@@ -3019,7 +3055,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
if ((ret.right() + gain) > widget->rect().right())
gain = widget->rect().right() - ret.right();
ret.adjust(0, 0, gain, 0);
- }
+ }
}
break;
}
@@ -3107,7 +3143,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
}
break;
case SE_ItemViewItemCheckIndicator:
- if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget);
const bool singleSelection = listItem &&
@@ -3115,7 +3151,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
listItem->selectionMode() == QAbstractItemView::NoSelection);
const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) &&
listItem &&
- singleSelection;
+ singleSelection && vopt->text.isEmpty() && vopt->icon.isNull();
// Selection check mark rect.
const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth);
@@ -3359,9 +3395,9 @@ bool QS60Style::event(QEvent *e)
QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option, const QWidget *widget) const
{
- const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize);
- const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect;
QS60StyleEnums::SkinParts part;
+ qreal iconHeightMultiplier = 1.0;
+ qreal iconWidthMultiplier = 1.0;
QS60StylePrivate::SkinElementFlags adjustedFlags;
if (option)
adjustedFlags = (option->state & State_Enabled || option->state == 0) ?
@@ -3370,15 +3406,20 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
switch(standardIcon) {
case SP_MessageBoxWarning:
+ // By default, S60 messagebox icons have 4:3 ratio. Value is from S60 LAF documentation.
+ iconHeightMultiplier = 1.33;
part = QS60StyleEnums::SP_QgnNoteWarning;
break;
case SP_MessageBoxInformation:
+ iconHeightMultiplier = 1.33;
part = QS60StyleEnums::SP_QgnNoteInfo;
break;
case SP_MessageBoxCritical:
+ iconHeightMultiplier = 1.33;
part = QS60StyleEnums::SP_QgnNoteError;
break;
case SP_MessageBoxQuestion:
+ iconHeightMultiplier = 1.33;
part = QS60StyleEnums::SP_QgnNoteQuery;
break;
case SP_ArrowRight:
@@ -3433,11 +3474,13 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
adjustedFlags |= QS60StylePrivate::SF_PointEast;
part = QS60StyleEnums::SP_QgnIndiSubmenu;
break;
-
default:
return QCommonStyle::standardIconImplementation(standardIcon, option, widget);
}
const QS60StylePrivate::SkinElementFlags flags = adjustedFlags;
+ const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize);
+ const QRect iconSize = (!option) ?
+ QRect(0, 0, iconDimension * iconWidthMultiplier, iconDimension * iconHeightMultiplier) : option->rect;
const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), 0, flags));
return cachedPixMap.isNull() ?
QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap);
@@ -3545,10 +3588,18 @@ extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget);
bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
{
- const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
- if (backgroundTexture.cacheKey() != brush.texture().cacheKey())
+ // Check if the widget's palette matches placeholder or actual background texture.
+ // When accessing backgroundTexture, use parameter value 'true' to avoid creating
+ // the texture, if it is not already created.
+
+ const QPixmap placeHolder(QS60StylePrivate::placeHolderTexture());
+ const QPixmap bg(QS60StylePrivate::backgroundTexture(true));
+ if (placeHolder.cacheKey() != brush.texture().cacheKey()
+ && bg.cacheKey() != brush.texture().cacheKey())
return false;
+ const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
+
const QPaintDevice *target = painter->device();
if (target->devType() == QInternal::Widget) {
const QWidget *widget = static_cast<const QWidget *>(target);
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 242c451..e146a4e 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -554,15 +554,14 @@ public:
static QPixmap frame(SkinFrameElements frame, const QSize &size,
SkinElementFlags flags = KDefaultSkinElementFlags);
- static QPixmap backgroundTexture();
+ static QPixmap backgroundTexture(bool skipCreation = false);
+ static QPixmap placeHolderTexture();
#ifdef Q_WS_S60
void handleDynamicLayoutVariantSwitch();
void handleSkinChange();
#endif // Q_WS_S60
- static QSize naviPaneSize();
-
//Checks that the current brush is transparent or has BrushStyle NoBrush,
//so that theme graphic background can be drawn.
static bool canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget);
@@ -592,13 +591,11 @@ private:
static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size,
SkinElementFlags flags = KDefaultSkinElementFlags);
- static void refreshUI();
-
// set S60 font for widget
void setFont(QWidget *widget) const;
- void setThemePalette(QWidget *widget) const;
+ static void setThemePalette(QWidget *widget);
void setThemePalette(QPalette *palette) const;
- void setThemePaletteHash(QPalette *palette) const;
+ static void setThemePaletteHash(QPalette *palette);
static void storeThemePalette(QPalette *palette);
static void deleteThemePalette();
static bool equalToThemePalette(QColor color, QPalette::ColorRole role);
@@ -616,6 +613,9 @@ private:
// Contains background texture.
static QPixmap *m_background;
+ // Placeholder pixmap for the real background texture.
+ static QPixmap *m_placeHolderTexture;
+
const static SkinElementFlags KDefaultSkinElementFlags;
// defined theme palette
static QPalette *m_themePalette;
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 605872e..7f19c35 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -47,6 +47,7 @@
#include "private/qt_s60_p.h"
#include "private/qpixmap_s60_p.h"
#include "private/qcore_symbian_p.h"
+#include "private/qvolatileimage_p.h"
#include "qapplication.h"
#include "qsettings.h"
@@ -65,7 +66,6 @@
#include <aknnavi.h>
#include <gulicon.h>
#include <AknBitmapAnimation.h>
-
#include <centralrepository.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
@@ -89,17 +89,25 @@ enum TSupportRelease {
ES60_5_0 = 0x0004,
ES60_5_1 = 0x0008,
ES60_5_2 = 0x0010,
+ ES60_5_3 = 0x0020,
ES60_3_X = ES60_3_1 | ES60_3_2,
// Releases before Symbian Foundation
ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
+ // Releases before the S60 5.2
+ ES60_Pre52 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
+ // Releases before S60 5.3
+ ES60_Pre53 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
// Add all new releases here
- ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2
+ ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
};
typedef struct {
- const TAknsItemID &skinID;
- TDrawType drawType;
- int supportInfo;
+ const TAknsItemID &skinID; // Determines default theme graphics ID.
+ TDrawType drawType; // Determines which native drawing routine is used to draw this item.
+ int supportInfo; // Defines the S60 versions that use the default graphics.
+ // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
+ // In general, these are given in numeric form to allow style compilation in earlier
+ // native releases that do not contain the new graphics.
int newMajorSkinId;
int newMinorSkinId;
} partMapEntry;
@@ -158,7 +166,6 @@ public:
static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static QSize naviPaneSize();
static TAknsItemID partSpecificThemeId(int part);
static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
@@ -189,12 +196,14 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
/* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
/* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
/* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1},
+
+ // In S60 5.3 there is a new tab graphic
+ /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
+ /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
+ /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
+ /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
+ /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
+ /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
// In 3.1 there is no slider groove.
/* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
@@ -637,9 +646,23 @@ QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask
if (error)
return QPixmap();
- QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(icon);
- if (mask)
- pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ QPixmap pixmap;
+ QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
+ if (mask) {
+ // Try the efficient path with less copying and conversion.
+ QVolatileImage img(icon, mask);
+ pd->fromNativeType(&img, QPixmapData::VolatileImage);
+ if (!pd->isNull())
+ pixmap = QPixmap(pd.take());
+ }
+ if (pixmap.isNull()) {
+ // Potentially more expensive path.
+ pd->fromNativeType(icon, QPixmapData::FbsBitmap);
+ pixmap = QPixmap(pd.take());
+ if (mask) {
+ pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ }
+ }
if ((flags & QS60StylePrivate::SF_PointEast) ||
(flags & QS60StylePrivate::SF_PointSouth) ||
@@ -795,6 +818,8 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
QPixmap result;
@@ -833,7 +858,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
// QS60WindowSurface::unlockBitmapHeap();
CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
CleanupStack::PushL(background);
- User::LeaveIfError(background->Create(targetSize, EColor16MA));
+ User::LeaveIfError(background->Create(targetSize, displayMode));
CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
CleanupStack::PushL(dev);
@@ -854,7 +879,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
*gc,
TPoint(),
targetSize,
- KAknsDrawParamDefault | KAknsDrawParamRGBOnly);
+ drawParam);
if (drawn)
result = fromFbsBitmap(background, NULL, flags, targetSize);
@@ -1125,7 +1150,8 @@ bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
(currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
(currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
(currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
- (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2));
+ (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
}
TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
@@ -1375,7 +1401,7 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin
return result;
}
-QPixmap QS60StylePrivate::backgroundTexture()
+QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
{
bool createNewBackground = false;
TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
@@ -1386,15 +1412,31 @@ QPixmap QS60StylePrivate::backgroundTexture()
if (m_background->width() != applicationRect.Width() ||
m_background->height() != applicationRect.Height()) {
delete m_background;
+ m_background = 0;
createNewBackground = true;
}
}
- if (createNewBackground) {
+ if (createNewBackground && !skipCreation) {
QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
+ QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
m_background = new QPixmap(background);
+
+ // Notify all widgets that palette is updated with the actual background texture.
+ QPalette pal = QApplication::palette();
+ pal.setBrush(QPalette::Window, *m_background);
+ QApplication::setPalette(pal);
+ setThemePaletteHash(&pal);
+ storeThemePalette(&pal);
+ foreach (QWidget *widget, QApplication::allWidgets()){
+ QEvent e(QEvent::PaletteChange);
+ QApplication::sendEvent(widget, &e);
+ setThemePalette(widget);
+ widget->ensurePolished();
+ }
}
+ if (!m_background)
+ return QPixmap();
return *m_background;
}
@@ -1412,8 +1454,8 @@ QS60Style::QS60Style()
void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
{
clearCaches(QS60StylePrivate::CC_LayoutChange);
+ setBackgroundTexture(qApp);
setActiveLayout();
- refreshUI();
foreach (QWidget *widget, QApplication::allWidgets())
widget->ensurePolished();
}
@@ -1435,23 +1477,6 @@ void QS60StylePrivate::handleSkinChange()
#endif
}
-QSize QS60StylePrivate::naviPaneSize()
-{
- return QS60StyleModeSpecifics::naviPaneSize();
-}
-
-QSize QS60StyleModeSpecifics::naviPaneSize()
-{
- CAknNavigationControlContainer* naviContainer;
- if (S60->statusPane()) {
- TRAPD(err, naviContainer = static_cast<CAknNavigationControlContainer*>
- (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi))));
- if (err==KErrNone)
- return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight);
- }
- return QSize(0,0);
-}
-
int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
{
QS60StyleAnimation *animation = animationDefinition(part);
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 77e0d0e..a5aeac3 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -308,7 +308,7 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size,
return result;
}
-QPixmap QS60StylePrivate::backgroundTexture()
+QPixmap QS60StylePrivate::backgroundTexture(bool /*skipCreation*/)
{
if (!m_background) {
const QSize size = QApplication::desktop()->screen()->size();
@@ -318,11 +318,6 @@ QPixmap QS60StylePrivate::backgroundTexture()
return *m_background;
}
-QSize QS60StylePrivate::naviPaneSize()
-{
- return QSize(0, 0);
-}
-
bool QS60StylePrivate::isTouchSupported()
{
#ifdef QT_KEYPAD_NAVIGATION
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index a4e7c38..369a0f0 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -3339,6 +3339,13 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
break;
+ case CE_FocusFrame:
+ if (!rule.hasNativeBorder()) {
+ rule.drawBorder(p, opt->rect);
+ return;
+ }
+ break;
+
case CE_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 1c21f91..05e3d3c 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -59,6 +59,8 @@
QT_BEGIN_NAMESPACE
+static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
+
/*****************************************************************************
QFontEngine debug facilities
*****************************************************************************/
@@ -142,7 +144,7 @@ void qmacfontengine_gamma_correct(QImage *image)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &atsFamilyRef, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
@@ -160,6 +162,8 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con
QCFString name;
ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
+ if (QString(name).isEmpty())
+ ATSFontFamilyGetName(atsFamilyRef, kATSOptionFlagsDefault, &name);
transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100) {
@@ -467,6 +471,9 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
glyph_metrics_t ret;
CGGlyph g = glyph;
CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1);
+ if (synthesisFlags & QFontEngine::SynthesizedItalic) {
+ rect.size.width += rect.size.height * SYNTHETIC_ITALIC_SKEW;
+ }
ret.width = QFixed::fromReal(rect.size.width);
ret.height = QFixed::fromReal(rect.size.height);
ret.x = QFixed::fromReal(rect.origin.x);
@@ -558,7 +565,7 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt
CGAffineTransformConcat(cgMatrix, oldTextMatrix);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
@@ -646,7 +653,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
for (int i = 0; i < nGlyphs; ++i) {
@@ -681,7 +688,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
CGAffineTransformConcat(cgMatrix, oldTextMatrix);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
@@ -1625,7 +1632,7 @@ QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful)
CGAffineTransformConcat(cgMatrix, oldTextMatrix);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
@@ -1718,7 +1725,7 @@ void QFontEngineMac::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt
CGAffineTransformConcat(cgMatrix, oldTextMatrix);
if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
+ cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h
index 501bfff..4057142 100644
--- a/src/gui/text/qfragmentmap_p.h
+++ b/src/gui/text/qfragmentmap_p.h
@@ -195,6 +195,10 @@ public:
head->root = new_root;
}
+ inline bool isValid(uint n) const {
+ return n > 0 && n != head->freelist;
+ }
+
union {
Header *head;
Fragment *fragments;
@@ -854,6 +858,7 @@ public:
return data.fragment(index);
}
inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
+ inline bool isValid(uint n) const { return data.isValid(n); }
inline uint next(uint n) const { return data.next(n); }
inline uint previous(uint n) const { return data.previous(n); }
inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index a1dcb63..5e59341 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -3148,7 +3148,7 @@ QRectF QTextDocumentLayoutPrivate::frameBoundingRectInternal(QTextFrame *frame)
QRectF QTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
{
Q_D(const QTextDocumentLayout);
- if (d->docPrivate->pageSize.isNull())
+ if (d->docPrivate->pageSize.isNull() || !block.isValid())
return QRectF();
d->ensureLayoutedByPosition(block.position() + block.length());
QTextFrame *frame = d->document->frameAt(block.position());
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index b511b5a..4f86cff 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1233,6 +1233,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
shaper_item.num_glyphs -= itemBoundaries[k + 1];
}
shaper_item.initialGlyphCount = shaper_item.num_glyphs;
+ if (shaper_item.num_glyphs < shaper_item.item.length)
+ shaper_item.num_glyphs = shaper_item.item.length;
QFontEngine *actualFontEngine = font;
uint engineIdx = 0;
@@ -1257,7 +1259,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
}
const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
- moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
+ if (shaper_item.num_glyphs > shaper_item.item.length)
+ moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
shaper_item.glyphs = g.glyphs;
shaper_item.attributes = g.attributes;
@@ -2678,6 +2681,22 @@ void QTextEngine::resolveAdditionalFormats() const
specialData->resolvedFormatIndices = indices;
}
+QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
+{
+ if (!line.hasTrailingSpaces
+ || (option.flags() & QTextOption::IncludeTrailingSpaces)
+ || !isRightToLeft())
+ return QFixed();
+
+ int pos = line.length;
+ const HB_CharAttributes *attributes = this->attributes();
+ if (!attributes)
+ return QFixed();
+ while (pos > 0 && attributes[line.from + pos - 1].whiteSpace)
+ --pos;
+ return width(line.from + pos, line.length - pos);
+}
+
QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)
: QTextEngine(string, f),
_layoutData(string, _memory, MemSize)
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp
index ce42241..c34bdb3 100644
--- a/src/gui/text/qtextengine_mac.cpp
+++ b/src/gui/text/qtextengine_mac.cpp
@@ -604,8 +604,9 @@ void QTextEngine::shapeTextMac(int item) const
bool stringToCMapFailed = false;
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
ensureSpace(num_glyphs);
- stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
- attributes());
+ g = availableGlyphs(&si);
+ stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
+ attributes());
}
if (!stringToCMapFailed) {
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 34723ab..67d7453 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -592,6 +592,7 @@ public:
QString elidedText(Qt::TextElideMode mode, const QFixed &width, int flags = 0) const;
void shapeLine(const QScriptLine &line);
+ QFixed leadingSpaceWidth(const QScriptLine &line);
private:
void setBoundary(int strPos) const;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index a996f59..692620f 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -64,23 +64,6 @@ QT_BEGIN_NAMESPACE
#define SuppressText 0x5012
#define SuppressBackground 0x513
-static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line)
-{
- if (!line.hasTrailingSpaces
- || (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
- || !(eng->option.alignment() & Qt::AlignRight)
- || !eng->isRightToLeft())
- return QFixed();
-
- int pos = line.length;
- const HB_CharAttributes *attributes = eng->attributes();
- if (!attributes)
- return QFixed();
- while (pos > 0 && attributes[line.from + pos - 1].whiteSpace)
- --pos;
- return eng->width(line.from + pos, line.length - pos);
-}
-
static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
{
QFixed x = 0;
@@ -91,7 +74,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
if (align & Qt::AlignJustify && eng->isRightToLeft())
align = Qt::AlignRight;
if (align & Qt::AlignRight)
- x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line));
+ x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line));
else if (align & Qt::AlignHCenter)
x = (line.width - line.textAdvance)/2;
}
@@ -1682,6 +1665,7 @@ namespace {
int glyphCount;
int maxGlyphs;
int currentPosition;
+ glyph_t previousGlyph;
QFixed minw;
QFixed softHyphenWidth;
@@ -1709,6 +1693,15 @@ namespace {
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
+ inline void saveCurrentGlyph()
+ {
+ previousGlyph = 0;
+ if (currentPosition > 0 &&
+ logClusters[currentPosition - 1] < glyphs.numGlyphs) {
+ previousGlyph = currentGlyph(); // needed to calculate right bearing later
+ }
+ }
+
inline void adjustRightBearing(glyph_t glyph)
{
qreal rb;
@@ -1723,6 +1716,12 @@ namespace {
adjustRightBearing(currentGlyph());
}
+ inline void adjustPreviousRightBearing()
+ {
+ if (previousGlyph > 0)
+ adjustRightBearing(previousGlyph);
+ }
+
inline void resetRightBearing()
{
rightBearing = QFixed(1); // Any positive number is defined as invalid since only
@@ -1798,22 +1797,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);
int item = -1;
- int newItem = -1;
- int left = 0;
- int right = eng->layoutData->items.size()-1;
- while(left <= right) {
- int middle = ((right-left)/2)+left;
- if (line.from > eng->layoutData->items[middle].position)
- left = middle+1;
- else if(line.from < eng->layoutData->items[middle].position)
- right = middle-1;
- else {
- newItem = middle;
- break;
- }
- }
- if (newItem == -1)
- newItem = right;
+ int newItem = eng->findItem(line.from);
LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal());
@@ -1825,6 +1809,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.currentPosition = line.from;
int end = 0;
lbh.logClusters = eng->layoutData->logClustersPtr;
+ lbh.previousGlyph = 0;
while (newItem < eng->layoutData->items.size()) {
lbh.resetRightBearing();
@@ -1885,6 +1870,7 @@ void QTextLine::layout_helper(int maxGlyphs)
current, lbh.logClusters, lbh.glyphs);
} else {
lbh.tmpData.length++;
+ lbh.adjustPreviousRightBearing();
}
line += lbh.tmpData;
goto found;
@@ -1915,9 +1901,7 @@ void QTextLine::layout_helper(int maxGlyphs)
} else {
lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
- glyph_t previousGlyph = 0;
- if (lbh.currentPosition > 0 && lbh.logClusters[lbh.currentPosition - 1] <lbh.glyphs.numGlyphs)
- previousGlyph = lbh.currentGlyph(); // needed to calculate right bearing later
+ lbh.saveCurrentGlyph();
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs);
@@ -1942,7 +1926,7 @@ void QTextLine::layout_helper(int maxGlyphs)
// b) if we are so short of available width that the
// soft hyphen is the first breakable position, then
// we don't want to show it. However we initially
- // have to take the width for it into accoun so that
+ // have to take the width for it into account so that
// the text document layout sees the overflow and
// switch to break-anywhere mode, in which we
// want the soft-hyphen to slip into the next line
@@ -1970,8 +1954,9 @@ void QTextLine::layout_helper(int maxGlyphs)
// we are too wide, fix right bearing
if (rightBearing <= 0)
lbh.rightBearing = rightBearing; // take from cache
- else if (previousGlyph > 0)
- lbh.adjustRightBearing(previousGlyph);
+ else
+ lbh.adjustPreviousRightBearing();
+
if (!breakany) {
line.textWidth += lbh.softHyphenWidth;
}
@@ -1979,6 +1964,7 @@ void QTextLine::layout_helper(int maxGlyphs)
goto found;
}
}
+ lbh.saveCurrentGlyph();
}
if (lbh.currentPosition == end)
newItem = item + 1;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index e323fd0..a403cc5 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -891,6 +891,11 @@ QTextBlockUserData::~QTextBlockUserData()
Returns true if this text block is valid; otherwise returns false.
*/
+bool QTextBlock::isValid() const
+{
+ return p != 0 && p->blockMap().isValid(n);
+}
+
/*!
\fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)
@@ -1504,7 +1509,7 @@ QTextBlock QTextBlock::next() const
*/
QTextBlock QTextBlock::previous() const
{
- if (!isValid())
+ if (!p)
return QTextBlock();
return QTextBlock(p, p->blockMap().previous(n));
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index d5c1e8d..73aed79 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -204,7 +204,7 @@ public:
inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {}
inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; }
- inline bool isValid() const { return p != 0 && n != 0; }
+ bool isValid() const;
inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; }
inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; }
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 96860df..8caeb74 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -314,7 +314,7 @@ static bool handleUrl(const QUrl &url)
if (!url.isValid())
return false;
- QString urlString(url.toString());
+ QString urlString(url.toEncoded());
TPtrC urlPtr(qt_QString2TPtrC(urlString));
TRAPD( err, handleUrlL(urlPtr));
return err ? false : true;
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 5104116..2503b99 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -500,7 +500,7 @@ QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget
/*!
Constructs a viewport.
- The \a parent arguments is sent to the QWidget constructor.
+ The \a parent argument is sent to the QWidget constructor.
*/
QAbstractScrollArea::QAbstractScrollArea(QWidget *parent)
:QFrame(*new QAbstractScrollAreaPrivate, parent)
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index cb36398..2570496 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -265,7 +265,7 @@ void QAbstractSliderPrivate::setSteps(int single, int page)
/*!
Constructs an abstract slider.
- The \a parent arguments is sent to the QWidget constructor.
+ The \a parent argument is sent to the QWidget constructor.
The \l minimum defaults to 0, the \l maximum to 99, with a \l
singleStep size of 1 and a \l pageStep size of 10, and an initial
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index dbbf49a..04ab801 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -398,7 +398,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *)
#ifdef Q_WS_MAC
QStyleOptionComboBox opt = comboStyleOption();
if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo))
- view->setCurrentIndex(QModelIndex());
+ view->clearSelection();
#endif
}
@@ -671,8 +671,8 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
blockMouseReleaseTimer.stop();
QModelIndex indexUnderMouse = view->indexAt(m->pos());
- if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()
- && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
+ if (indexUnderMouse.isValid()
+ && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
view->setCurrentIndex(indexUnderMouse);
}
}
@@ -704,11 +704,13 @@ void QComboBoxPrivateContainer::hideEvent(QHideEvent *)
{
emit resetButton();
combo->update();
+#ifndef QT_NO_GRAPHICSVIEW
// QGraphicsScenePrivate::removePopup closes the combo box popup, it hides it non-explicitly.
// Hiding/showing the QComboBox after this will unexpectedly show the popup as well.
// Re-hiding the popup container makes sure it is explicitly hidden.
if (QGraphicsProxyWidget *proxy = graphicsProxyWidget())
proxy->hide();
+#endif
}
void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e)
@@ -944,7 +946,10 @@ QComboBox::QComboBox(bool rw, QWidget *parent, const char *name)
to set and get item data (e.g., setItemData() and itemText()). You
can also set a new model and view (with setModel() and setView()).
For the text and icon in the combobox label, the data in the model
- that has the Qt::DisplayRole and Qt::DecorationRole is used.
+ that has the Qt::DisplayRole and Qt::DecorationRole is used. Note
+ that you cannot alter the \l{QAbstractItemView::}{SelectionMode}
+ of the view(), e.g., by using
+ \l{QAbstractItemView::}{setSelectionMode()}.
\image qstyle-comboboxes.png Comboboxes in the different built-in styles.
@@ -2453,12 +2458,7 @@ void QComboBox::showPopup()
// available screen geometry.This may override the vertical position, but it is more
// important to show as much as possible of the popup.
const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height());
-#ifdef Q_WS_S60
- //popup needs to be stretched with screen minimum dimension
- listRect.setHeight(qMin(screen.height(), screen.width()));
-#else
listRect.setHeight(height);
-#endif
if (boundToScreen) {
if (listRect.top() < screen.top())
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 9a6d24c..2f4bb4b 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -1247,37 +1247,15 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action)
response to button presses; these are just like context menus
except for how they are invoked.
- \raw HTML
- <table align="center" cellpadding="0">
- <tr>
- <td>
- \endraw
- \inlineimage plastique-menu.png
- \raw HTML
- </td>
- <td>
- \endraw
- \inlineimage windowsxp-menu.png
- \raw HTML
- </td>
- <td>
- \endraw
- \inlineimage macintosh-menu.png
- \raw HTML
- </td>
-
- </tr>
- <tr>
- <td colspan="3">
- \endraw
- A menu shown in \l{Plastique Style Widget Gallery}{Plastique widget style},
+ \table 100%
+ \row
+ \o \inlineimage plastique-menu.png
+ \o \inlineimage windowsxp-menu.png
+ \o \inlineimage macintosh-menu.png
+ \endtable
+ \caption Fig. A menu shown in \l{Plastique Style Widget Gallery}{Plastique widget style},
\l{Windows XP Style Widget Gallery}{Windows XP widget style},
and \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \raw HTML
- </td>
- </tr>
- </table>
- \endraw
\section1 Actions
diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp
index c895b1b..87738a0 100644
--- a/src/gui/widgets/qscrollbar.cpp
+++ b/src/gui/widgets/qscrollbar.cpp
@@ -330,7 +330,7 @@ void QScrollBar::initStyleOption(QStyleOptionSlider *option) const
/*!
Constructs a vertical scroll bar.
- The \a parent arguments is sent to the QWidget constructor.
+ The \a parent argument is sent to the QWidget constructor.
The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the
\l {QAbstractSlider::maximum} {maximum} to 99, with a
diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp
index 964a6e1..ca8fc37 100644
--- a/src/gui/widgets/qsplitter.cpp
+++ b/src/gui/widgets/qsplitter.cpp
@@ -1016,7 +1016,7 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
/*!
Constructs a horizontal splitter with the \a parent
- arguments is passed on to the QFrame constructor.
+ argument passed on to the QFrame constructor.
\sa setOrientation()
*/
diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp
index c2a2e98..aae6a01 100644
--- a/src/imports/gestures/qdeclarativegesturearea.cpp
+++ b/src/imports/gestures/qdeclarativegesturearea.cpp
@@ -136,7 +136,7 @@ public:
GestureArea is an invisible item: it is never painted.
- \sa MouseArea, {declarative/touchinteraction/gestures}{Gestures example}
+ \sa MouseArea
*/
/*!
diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp
index 3767b95..77ecf70 100644
--- a/src/multimedia/audio/qaudioinput.cpp
+++ b/src/multimedia/audio/qaudioinput.cpp
@@ -202,7 +202,13 @@ QAudioInput::~QAudioInput()
/*!
Uses the \a device as the QIODevice to transfer data.
Passing a QIODevice allows the data to be transferred without any extra code.
- All that is required is to open the QIODevice.
+ All that is required is to open the QIODevice. QAudioInput does not take
+ ownership of \a device.
+
+ The QAudioInput will write to the device when new data is available. You can
+ subclass QIODevice and reimplement \l{QIODevice::}{writeData()} if you wish to
+ access the data. If you simply want to save data to a file, you can pass a
+ QFile to this function.
If able to successfully get audio data from the systems audio device the
state() is set to either QAudio::ActiveState or QAudio::IdleState,
@@ -222,9 +228,12 @@ void QAudioInput::start(QIODevice* device)
}
/*!
- Returns a pointer to the QIODevice being used to handle the data
- transfer. This QIODevice can be used to read() audio data
- directly.
+
+ Returns a pointer to a new QIODevice that will be used to handle the data transfer.
+ This QIODevice can be used to \l{QIODevice::}{read()} audio data directly.
+ You will typically connect to the \l{QIODevice::}{readyRead()} signal, and
+ read from the device in the slot you connect to. QAudioInput keeps ownership
+ of the device.
If able to access the systems audio device the state() is set to
QAudio::IdleState, error() is set to QAudio::NoError
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index ccc20e6..69e59d1 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -363,9 +363,9 @@ qint64 QFtpDTP::read(char *data, qint64 maxlen)
if (socket && socket->state() == QTcpSocket::ConnectedState) {
read = socket->read(data, maxlen);
} else {
- read = bytesFromSocket.size();
+ read = qMin(maxlen, qint64(bytesFromSocket.size()));
memcpy(data, bytesFromSocket.data(), read);
- bytesFromSocket.clear();
+ bytesFromSocket.remove(0, read);
}
bytesDone += read;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 82b5ce3..700b455 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -963,8 +963,20 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
} else {
errorCode = QNetworkReply::RemoteHostClosedError;
}
+ } else if (state == QHttpNetworkConnectionChannel::ReadingState) {
+ if (!reply->d_func()->expectContent()) {
+ // No content expected, this is a valid way to have the connection closed by the server
+ return;
+ }
+ if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) {
+ // There was no content-length header and it's not chunked encoding,
+ // so this is a valid way to have the connection closed by the server
+ return;
+ }
+ // ok, we got a disconnect even though we did not expect it
+ errorCode = QNetworkReply::RemoteHostClosedError;
} else {
- return;
+ errorCode = QNetworkReply::RemoteHostClosedError;
}
break;
case QAbstractSocket::SocketTimeoutError:
@@ -992,6 +1004,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (reply) {
reply->d_func()->errorString = errorString;
emit reply->finishedWithError(errorCode, errorString);
+ reply = 0;
}
// send the next request
QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 4189743..7c90f68 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -360,6 +360,11 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest,
return;
}
+ // The disk cache API does not currently support partial content retrieval.
+ // That is why we don't use the disk cache for any such requests.
+ if (request().hasRawHeader("Range"))
+ return;
+
QAbstractNetworkCache *nc = networkCache();
if (!nc)
return; // no local cache
@@ -996,14 +1001,11 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
if (hop_by_hop)
continue;
- // for 4.6.0, we were planning to not store the date header in the
- // cached resource; through that we planned to reduce the number
- // of writes to disk when using a QNetworkDiskCache (i.e. don't
- // write to disk when only the date changes).
- // However, without the date we cannot calculate the age of the page
- // anymore.
- //if (header == "date")
- //continue;
+ // we are currently not using the date header to determine the expiration time of a page,
+ // but only the "Expires", "max-age" and "s-maxage" headers, see
+ // QNetworkAccessHttpBackend::validateCache() and below ("metaData.setExpirationDate()").
+ if (header == "date")
+ continue;
// Don't store Warning 1xx headers
if (header == "warning") {
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 70ea5c2..c2a6925 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -359,7 +359,7 @@ void QNetworkCookie::setValue(const QByteArray &value)
}
// ### move this to qnetworkcookie_p.h and share with qnetworkaccesshttpbackend
-static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position)
+static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position, bool isNameValue)
{
// format is one of:
// (1) token
@@ -394,13 +394,22 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi
// quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
// qdtext = <any TEXT except <">>
// quoted-pair = "\" CHAR
+
+ // If its NAME=VALUE, retain the value as is
+ // refer to ttp://bugreports.qt.nokia.com/browse/QTBUG-17746
+ if (isNameValue)
+ second += '"';
++i;
while (i < length) {
register char c = text.at(i);
if (c == '"') {
// end of quoted text
+ if (isNameValue)
+ second += '"';
break;
} else if (c == '\\') {
+ if (isNameValue)
+ second += '\\';
++i;
if (i >= length)
// broken line
@@ -476,10 +485,12 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const
result = d->name;
result += '=';
- if (d->value.contains(';') ||
+ if ((d->value.contains(';') ||
d->value.contains(',') ||
d->value.contains(' ') ||
- d->value.contains('"')) {
+ d->value.contains('"')) &&
+ (!d->value.startsWith('"') &&
+ !d->value.endsWith('"'))) {
result += '"';
QByteArray value = d->value;
@@ -947,7 +958,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
QNetworkCookie cookie;
// The first part is always the "NAME=VALUE" part
- QPair<QByteArray,QByteArray> field = nextField(cookieString, position);
+ QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true);
if (field.first.isEmpty() || field.second.isNull())
// parsing error
break;
@@ -965,7 +976,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
case ';':
// new field in the cookie
- field = nextField(cookieString, position);
+ field = nextField(cookieString, position, false);
field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive
if (field.first == "expires") {
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 343f344..894df79 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -505,6 +505,13 @@ void QNetworkReplyImplPrivate::initCacheSaveDevice()
{
Q_Q(QNetworkReplyImpl);
+ // The disk cache does not support partial content, so don't even try to
+ // save any such content into the cache.
+ if (q->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 206) {
+ cacheEnabled = false;
+ return;
+ }
+
// save the meta data
QNetworkCacheMetaData metaData;
metaData.setUrl(url);
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 0e3c519..8634b6b 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -57,16 +57,17 @@ QT_BEGIN_NAMESPACE
{ \
delete this_##NAME.pointer; \
this_##NAME.pointer = 0; \
- this_##NAME.destroyed = true; \
} \
static TYPE *NAME() \
{ \
- if (!this_##NAME.pointer && !this_##NAME.destroyed) { \
+ if (!this_##NAME.pointer) { \
TYPE *x = new TYPE; \
if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \
delete x; \
- else \
+ else { \
qAddPostRoutine(NAME##_cleanup); \
+ this_##NAME.pointer->updateConfigurations(); \
+ } \
} \
return this_##NAME.pointer; \
}
@@ -75,15 +76,7 @@ Q_GLOBAL_STATIC_QAPP_DESTRUCTION(QNetworkConfigurationManagerPrivate, connManage
QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
{
- static bool initialized = false;
-
- QNetworkConfigurationManagerPrivate *m = connManager();
- if (!initialized) {
- initialized = true;
- m->updateConfigurations();
- }
-
- return m;
+ return connManager();
}
/*!
@@ -203,6 +196,9 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
/*!
Constructs a QNetworkConfigurationManager with the given \a parent.
+
+ Note that to ensure a valid list of current configurations immediately available, updating
+ is done during construction which causes some delay.
*/
QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent )
: QObject(parent)
diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h
index e107c62..ee28e64 100644
--- a/src/network/bearer/qnetworksession.h
+++ b/src/network/bearer/qnetworksession.h
@@ -141,13 +141,12 @@ private:
#ifndef QT_MOBILITY_BEARER
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QNetworkSession::State)
+Q_DECLARE_METATYPE(QNetworkSession::SessionError)
#else
QTM_END_NAMESPACE
#endif
-Q_DECLARE_METATYPE(QNetworkSession::State)
-Q_DECLARE_METATYPE(QNetworkSession::SessionError)
-
QT_END_HEADER
#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp
index 51b3a32..fcb0128 100644
--- a/src/network/bearer/qsharednetworksession.cpp
+++ b/src/network/bearer/qsharednetworksession.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -59,6 +59,11 @@ inline QSharedNetworkSessionManager* sharedNetworkSessionManager()
return rv;
}
+static void doDeleteLater(QObject* obj)
+{
+ obj->deleteLater();
+}
+
QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(QNetworkConfiguration config)
{
QSharedNetworkSessionManager *m(sharedNetworkSessionManager());
@@ -69,7 +74,7 @@ QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(QNetwor
return p;
}
//otherwise make one
- QSharedPointer<QNetworkSession> session(new QNetworkSession(config));
+ QSharedPointer<QNetworkSession> session(new QNetworkSession(config), doDeleteLater);
m->sessions[config] = session;
return session;
}
diff --git a/src/network/kernel/qnetworkinterface_symbian.cpp b/src/network/kernel/qnetworkinterface_symbian.cpp
index 03133d0..8e5db3c 100644
--- a/src/network/kernel/qnetworkinterface_symbian.cpp
+++ b/src/network/kernel/qnetworkinterface_symbian.cpp
@@ -43,7 +43,7 @@
#include "qnetworkinterface.h"
#include "qnetworkinterface_p.h"
-#include "../corelib/kernel/qcore_symbian_p.h"
+#include <private/qcore_symbian_p.h>
#ifndef QT_NO_NETWORKINTERFACE
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 618ac79..a5cdf01 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -219,17 +219,19 @@ bool QSslCertificate::isNull() const
Returns true if this certificate is valid; otherwise returns
false.
- Note: Currently, this function only checks that the current
+ Note: Currently, this function checks that the current
data-time is within the date-time range during which the
- certificate is considered valid. No other checks are
- currently performed.
+ certificate is considered valid, and checks that the
+ certificate is not in a blacklist of fraudulent certificates.
\sa isNull()
*/
bool QSslCertificate::isValid() const
{
const QDateTime currentTime = QDateTime::currentDateTime();
- return currentTime >= d->notValidBefore && currentTime <= d->notValidAfter;
+ return currentTime >= d->notValidBefore &&
+ currentTime <= d->notValidAfter &&
+ ! QSslCertificatePrivate::isBlacklisted(*this);
}
/*!
@@ -798,6 +800,30 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr
return certificates;
}
+// These certificates are known to be fraudulent and were created during the comodo
+// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html
+static const char *certificate_blacklist[] = {
+ "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e",
+ "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06",
+ "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3",
+ "39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29",
+ "3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71",
+ "e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47",
+ "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43",
+ "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0",
+ "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0",
+ 0
+};
+
+bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate)
+{
+ for (int a = 0; certificate_blacklist[a] != 0; a++) {
+ if (certificate.serialNumber() == certificate_blacklist[a])
+ return true;
+ }
+ return false;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QSslCertificate &certificate)
{
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index cdceb0f..1ce33d3 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -96,6 +96,7 @@ public:
static QSslCertificate QSslCertificate_from_X509(X509 *x509);
static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1);
static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1);
+ static bool isBlacklisted(const QSslCertificate &certificate);
friend class QSslSocketBackendPrivate;
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 84e14ff..2427193 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -312,9 +312,18 @@ init_context:
q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle());
}
}
+
+ bool addExpiredCerts = true;
+#if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
+ //On Leopard SSL does not work if we add the expired certificates.
+ if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
+ addExpiredCerts = false;
+#endif
// now add the expired certs
- foreach (const QSslCertificate &caCertificate, expiredCerts) {
- q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle());
+ if (addExpiredCerts) {
+ foreach (const QSslCertificate &caCertificate, expiredCerts) {
+ q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle());
+ }
}
// Register a custom callback to get all verification errors.
@@ -1184,6 +1193,13 @@ bool QSslSocketBackendPrivate::startHandshake()
X509 *x509 = q_SSL_get_peer_certificate(ssl);
configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
q_X509_free(x509);
+ if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) {
+ q->setErrorString(QSslSocket::tr("The peer certificate is blacklisted"));
+ q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
+ emit q->error(QAbstractSocket::SslHandshakeFailedError);
+ plainSocket->disconnectFromHost();
+ return false;
+ }
// Start translating errors.
QList<QSslError> errors;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index cda31e5..5c8d2b6 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -90,10 +90,6 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_SYMBIAN)
-#define QT_GL_NO_SCISSOR_TEST
-#endif
-
#if defined(Q_WS_WIN)
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif
@@ -1335,11 +1331,14 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
ensureActive();
d->transferMode(ImageDrawingMode);
+ QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption|QGLContext::CanFlipNativePixmapBindOption;
+#ifdef QGL_USE_TEXTURE_POOL
+ bindOptions |= QGLContext::TemporarilyCachedBindOption;
+#endif
+
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture =
- ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption
- | QGLContext::CanFlipNativePixmapBindOption);
+ ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions);
GLfloat top = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.top()) : src.top();
GLfloat bottom = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.bottom()) : src.bottom();
@@ -1351,6 +1350,12 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
+
+ if (texture->options&QGLContext::TemporarilyCachedBindOption) {
+ // pixmap was temporarily cached as a QImage texture by pooling system
+ // and should be destroyed immediately
+ QGLTextureCache::instance()->remove(ctx, texture->id);
+ }
}
void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,
@@ -1375,12 +1380,23 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
+ QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption;
+#ifdef QGL_USE_TEXTURE_POOL
+ bindOptions |= QGLContext::TemporarilyCachedBindOption;
+#endif
+
+ QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, bindOptions);
GLuint id = texture->id;
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
+
+ if (texture->options&QGLContext::TemporarilyCachedBindOption) {
+ // image was temporarily cached by texture pooling system
+ // and should be destroyed immediately
+ QGLTextureCache::instance()->remove(ctx, texture->id);
+ }
}
void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 0e82467..6d79584 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -148,11 +148,16 @@ embedded {
}
symbian {
+ DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
+ SOURCES -= qpixmapdata_gl.cpp
SOURCES += qgl_symbian.cpp \
+ qpixmapdata_poolgl.cpp \
qglpixelbuffer_egl.cpp \
- qgl_egl.cpp
+ qgl_egl.cpp \
+ qgltexturepool.cpp
- HEADERS += qgl_egl_p.h
+ HEADERS += qgl_egl_p.h \
+ qgltexturepool_p.h
symbian:TARGET.UID3 = 0x2002131A
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 062218c..b755153 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -69,6 +69,7 @@
#if !defined(QT_OPENGL_ES_1)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
+#include <private/qwindowsurface_gl_p.h>
#endif
#ifndef QT_OPENGL_ES_2
@@ -86,13 +87,16 @@
#include <private/qpixmapdata_p.h>
#include <private/qpixmapdata_gl_p.h>
#include <private/qglpixelbuffer_p.h>
-#include <private/qwindowsurface_gl_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include "qcolormap.h"
#include "qfile.h"
#include "qlibrary.h"
#include <qmutex.h>
+#ifdef QGL_USE_TEXTURE_POOL
+#include <private/qgltexturepool_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -2022,6 +2026,10 @@ struct DDSFormat {
the pixmap/image that it stems from, e.g. installing destruction
hooks in them.
+ \omitvalue TemporarilyCachedBindOption Used by paint engines on some
+ platforms to indicate that the pixmap or image texture is possibly
+ cached only temporarily and must be destroyed immediately after the use.
+
\omitvalue InternalBindOption
*/
@@ -2529,8 +2537,18 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
const QImage &constRef = img; // to avoid detach in bits()...
+#ifdef QGL_USE_TEXTURE_POOL
+ QGLTexturePool::instance()->createPermanentTexture(tx_id,
+ target,
+ 0, internalFormat,
+ img.width(), img.height(),
+ externalFormat,
+ pixel_type,
+ constRef.bits());
+#else
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
+#endif
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
@@ -2569,7 +2587,6 @@ QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum targe
return 0;
}
-
/*! \internal */
QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options)
{
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 9443c74..7d72c8a 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -329,6 +329,7 @@ public:
MemoryManagedBindOption = 0x0010, // internal flag
CanFlipNativePixmapBindOption = 0x0020, // internal flag
+ TemporarilyCachedBindOption = 0x0040, // internal flag
DefaultBindOption = LinearFilteringBindOption
| InvertedYBindOption
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 674d80d..d6b2d3b 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <QtCore/qdebug.h>
#include <QtOpenGL/qgl.h>
#include <QtOpenGL/qglpixelbuffer.h>
#include "qgl_p.h"
@@ -195,6 +196,7 @@ void QGLContext::makeCurrent()
// PowerVR MBX/SGX chips needs to clear all buffers when starting to render
// a new frame, otherwise there will be a performance penalty to pay for
// each frame.
+ qDebug() << "Found SGX/MBX driver, enabling FullClearOnEveryFrame";
d->workaround_needsFullClearOnEveryFrame = true;
// Older PowerVR SGX drivers (like the one in the N900) have a
@@ -202,10 +204,31 @@ void QGLContext::makeCurrent()
// or GL_ALPHA texture bound to an FBO. The only way to
// identify that driver is to check the EGL version number for it.
const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION);
- if (egl_version && strstr(egl_version, "1.3"))
+
+ if (egl_version && strstr(egl_version, "1.3")) {
+ qDebug() << "Found v1.3 driver, enabling brokenFBOReadBack";
d->workaround_brokenFBOReadBack = true;
- else if (egl_version && strstr(egl_version, "1.4"))
+ } else if (egl_version && strstr(egl_version, "1.4")) {
+ qDebug() << "Found v1.4 driver, enabling brokenTexSubImage";
d->workaround_brokenTexSubImage = true;
+
+ // this is a bit complicated; 1.4 version SGX drivers from
+ // Nokia have fixed the brokenFBOReadBack problem, but
+ // official drivers from TI haven't, meaning that things
+ // like the beagleboard are broken unless we hack around it
+ // - but at the same time, we want to not reduce performance
+ // by not enabling this elsewhere.
+ //
+ // so, let's check for a Nokia-specific addon, and only
+ // enable if it isn't present.
+ // (see MeeGo bug #5616)
+ if (!QEgl::hasExtension("EGL_NOK_image_shared")) {
+ // no Nokia extension, this is probably a standard SGX
+ // driver, so enable the workaround
+ qDebug() << "Found non-Nokia v1.4 driver, enabling brokenFBOReadBack";
+ d->workaround_brokenFBOReadBack = true;
+ }
+ }
}
}
}
diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp
index 82b66f5..1b41db4 100644
--- a/src/opengl/qgl_symbian.cpp
+++ b/src/opengl/qgl_symbian.cpp
@@ -41,15 +41,17 @@
#include "qgl.h"
-#include <coemain.h>
-#include <coecntrl.h>
-#include <w32std.h>
+#include <fbs.h>
+#include <private/qt_s60_p.h>
#include <private/qpixmap_s60_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include <private/qgl_p.h>
#include <private/qpaintengine_opengl_p.h>
#include <private/qwidget_p.h> // to access QWExtra
+#include <private/qnativeimagehandleprovider_p.h>
#include "qgl_egl_p.h"
+#include "qpixmapdata_gl_p.h"
+#include "qgltexturepool_p.h"
#include "qcolormap.h"
#include <QDebug>
@@ -69,6 +71,8 @@ QT_BEGIN_NAMESPACE
#endif
#endif
+extern int qt_gl_pixmap_serial;
+
/*
QGLTemporaryContext implementation
*/
@@ -225,13 +229,20 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as
d->eglSurface = QEgl::createSurface(device(), d->eglContext->config());
-#if !defined(QGL_NO_PRESERVED_SWAP)
- eglGetError(); // Clear error state first.
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (eglGetError() != EGL_SUCCESS) {
- qWarning("QGLContext: could not enable preserved swap");
- }
+ eglGetError(); // Clear error state first.
+
+#ifdef QGL_NO_PRESERVED_SWAP
+ eglSurfaceAttrib(QEgl::display(), d->eglSurface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLContext: could not enable destroyed swap behaviour");
+#else
+ eglSurfaceAttrib(QEgl::display(), d->eglSurface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLContext: could not enable preserved swap behaviour");
#endif
setWindowCreated(true);
@@ -358,5 +369,104 @@ void QGLWidgetPrivate::recreateEglSurface()
eglSurfaceWindowId = currentId;
}
-QT_END_NAMESPACE
+static inline bool knownGoodFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16: // EColor64K
+ case QImage::Format_RGB32: // EColor16MU
+ case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
+ return true;
+ default:
+ return false;
+ }
+}
+
+void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
+{
+ if (type == QPixmapData::FbsBitmap) {
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
+ QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
+ if (size.width() == w && size.height() == h)
+ setSerialNumber(++qt_gl_pixmap_serial);
+ resize(size.width(), size.height());
+ m_source = QVolatileImage(bitmap);
+ if (pixelType() == BitmapType) {
+ m_source.ensureFormat(QImage::Format_MonoLSB);
+ } else if (!knownGoodFormat(m_source.format())) {
+ m_source.beginDataAccess();
+ QImage::Format format = idealFormat(m_source.imageRef(), Qt::AutoColor);
+ m_source.endDataAccess(true);
+ m_source.ensureFormat(format);
+ }
+ m_hasAlpha = m_source.hasAlphaChannel();
+ m_hasFillColor = false;
+ m_dirty = true;
+
+ } else if (type == QPixmapData::VolatileImage && pixmap) {
+ // Support QS60Style in more efficient skin graphics retrieval.
+ QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
+ if (img->width() == w && img->height() == h)
+ setSerialNumber(++qt_gl_pixmap_serial);
+ resize(img->width(), img->height());
+ m_source = *img;
+ m_hasAlpha = m_source.hasAlphaChannel();
+ m_hasFillColor = false;
+ m_dirty = true;
+ } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
+ destroyTexture();
+ nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
+ // Cannot defer the retrieval, we need at least the size right away.
+ createFromNativeImageHandleProvider();
+ }
+}
+void* QGLPixmapData::toNativeType(NativeType type)
+{
+ if (type == QPixmapData::FbsBitmap) {
+ if (m_source.isNull())
+ m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
+ return m_source.duplicateNativeImage();
+ }
+
+ return 0;
+}
+
+bool QGLPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
+{
+ if (type == QLatin1String("RSgImage")) {
+ fromNativeType(handle, QPixmapData::SgImage);
+ return true;
+ } else if (type == QLatin1String("CFbsBitmap")) {
+ fromNativeType(handle, QPixmapData::FbsBitmap);
+ return true;
+ }
+ return false;
+}
+
+void QGLPixmapData::createFromNativeImageHandleProvider()
+{
+ void *handle = 0;
+ QString type;
+ nativeImageHandleProvider->get(&handle, &type);
+ if (handle) {
+ if (initFromNativeImageHandle(handle, type)) {
+ nativeImageHandle = handle;
+ nativeImageType = type;
+ } else {
+ qWarning("QGLPixmapData: Unknown native image type '%s'", qPrintable(type));
+ }
+ } else {
+ qWarning("QGLPixmapData: Native handle is null");
+ }
+}
+
+void QGLPixmapData::releaseNativeImageHandle()
+{
+ if (nativeImageHandleProvider && nativeImageHandle) {
+ nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
+ nativeImageHandle = 0;
+ nativeImageType = QString();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index ae61ca1..0e879df 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -43,13 +43,13 @@
#include <private/qgl_p.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qglframebufferobject_p.h>
-#include <private/qwindowsurface_gl_p.h>
#ifdef Q_WS_X11
#include <private/qpixmapdata_x11gl_p.h>
#endif
#if !defined(QT_OPENGL_ES_1)
#include <private/qpixmapdata_gl_p.h>
+#include <private/qwindowsurface_gl_p.h>
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
new file mode 100644
index 0000000..a5472ec
--- /dev/null
+++ b/src/opengl/qgltexturepool.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgltexturepool_p.h"
+#include "qpixmapdata_gl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
+
+static QGLTexturePool *qt_gl_texture_pool = 0;
+
+class QGLTexturePoolPrivate
+{
+public:
+ QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {}
+
+ QGLPixmapData *lruFirst;
+ QGLPixmapData *lruLast;
+};
+
+QGLTexturePool::QGLTexturePool()
+ : d_ptr(new QGLTexturePoolPrivate())
+{
+}
+
+QGLTexturePool::~QGLTexturePool()
+{
+}
+
+QGLTexturePool *QGLTexturePool::instance()
+{
+ if (!qt_gl_texture_pool)
+ qt_gl_texture_pool = new QGLTexturePool();
+ return qt_gl_texture_pool;
+}
+
+GLuint QGLTexturePool::createTextureForPixmap(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ QGLPixmapData *data)
+{
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(target, texture);
+ do {
+ glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ if (data)
+ moveToHeadOfLRU(data);
+ return texture;
+ } else if (error != GL_OUT_OF_MEMORY) {
+ qWarning("QGLTexturePool: cannot create temporary texture because of invalid params");
+ return 0;
+ }
+ } while (reclaimSpace(internalformat, width, height, format, type, data));
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ width, height);
+ return 0;
+}
+
+bool QGLTexturePool::createPermanentTexture(GLuint texture,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data)
+{
+ glBindTexture(target, texture);
+ do {
+ glTexImage2D(target, level, internalformat, width, height, 0, format, type, data);
+
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ return true;
+ } else if (error != GL_OUT_OF_MEMORY) {
+ qWarning("QGLTexturePool: cannot create permanent texture because of invalid params");
+ return false;
+ }
+ } while (reclaimSpace(internalformat, width, height, format, type, 0));
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ width, height);
+ return 0;
+}
+
+void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
+{
+ // Very simple strategy at the moment: just destroy the texture.
+ if (data)
+ removeFromLRU(data);
+
+ QGLWidget *shareWidget = qt_gl_share_widget();
+ if (shareWidget) {
+ QGLShareContextScope ctx(shareWidget->context());
+ glDeleteTextures(1, &texture);
+ }
+}
+
+void QGLTexturePool::useTexture(QGLPixmapData *data)
+{
+ moveToHeadOfLRU(data);
+}
+
+void QGLTexturePool::detachTexture(QGLPixmapData *data)
+{
+ removeFromLRU(data);
+}
+
+bool QGLTexturePool::reclaimSpace(GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ QGLPixmapData *data)
+{
+ Q_UNUSED(internalformat); // For future use in picking the best texture to eject.
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+ Q_UNUSED(format);
+ Q_UNUSED(type);
+
+ bool succeeded = false;
+ bool wasInLRU = false;
+ if (data) {
+ wasInLRU = data->inLRU;
+ moveToHeadOfLRU(data);
+ }
+
+ QGLPixmapData *lrudata = pixmapLRU();
+ if (lrudata && lrudata != data) {
+ lrudata->reclaimTexture();
+ succeeded = true;
+ }
+
+ if (data && !wasInLRU)
+ removeFromLRU(data);
+
+ return succeeded;
+}
+
+void QGLTexturePool::hibernate()
+{
+ Q_D(QGLTexturePool);
+ QGLPixmapData *pd = d->lruLast;
+ while (pd) {
+ QGLPixmapData *prevLRU = pd->prevLRU;
+ pd->inTexturePool = false;
+ pd->inLRU = false;
+ pd->nextLRU = 0;
+ pd->prevLRU = 0;
+ pd->hibernate();
+ pd = prevLRU;
+ }
+ d->lruFirst = 0;
+ d->lruLast = 0;
+}
+
+void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data)
+{
+ Q_D(QGLTexturePool);
+ if (data->inLRU) {
+ if (!data->prevLRU)
+ return; // Already at the head of the list.
+ removeFromLRU(data);
+ }
+ data->inLRU = true;
+ data->nextLRU = d->lruFirst;
+ data->prevLRU = 0;
+ if (d->lruFirst)
+ d->lruFirst->prevLRU = data;
+ else
+ d->lruLast = data;
+ d->lruFirst = data;
+}
+
+void QGLTexturePool::removeFromLRU(QGLPixmapData *data)
+{
+ Q_D(QGLTexturePool);
+ if (!data->inLRU)
+ return;
+ if (data->nextLRU)
+ data->nextLRU->prevLRU = data->prevLRU;
+ else
+ d->lruLast = data->prevLRU;
+ if (data->prevLRU)
+ data->prevLRU->nextLRU = data->nextLRU;
+ else
+ d->lruFirst = data->nextLRU;
+ data->inLRU = false;
+}
+
+QGLPixmapData *QGLTexturePool::pixmapLRU()
+{
+ Q_D(QGLTexturePool);
+ return d->lruLast;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h
new file mode 100644
index 0000000..8b6f726
--- /dev/null
+++ b/src/opengl/qgltexturepool_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLTEXTUREPOOL_P_H
+#define QGLTEXTUREPOOL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgl.h"
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGLPixmapData;
+class QGLTexturePoolPrivate;
+
+class QGLTexturePool
+{
+public:
+ QGLTexturePool();
+ virtual ~QGLTexturePool();
+
+ static QGLTexturePool *instance();
+
+ // Create a new texture with the specified parameters and associate
+ // it with "data". The QGLPixmapData will be notified when the
+ // texture needs to be reclaimed by the pool.
+ //
+ // This function will call reclaimSpace() when texture creation fails.
+ GLuint createTextureForPixmap(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ QGLPixmapData *data);
+
+ // Create a permanent texture with the specified parameters.
+ // If there is insufficient space for the texture,
+ // then this function will call reclaimSpace() and try again.
+ //
+ // The caller is responsible for calling glDeleteTextures()
+ // when it no longer needs the texture, as the texture is not
+ // recorded in the texture pool.
+ bool createPermanentTexture(GLuint texture,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data);
+
+ // Release a texture that is no longer required.
+ void releaseTexture(QGLPixmapData *data, GLuint texture);
+
+ // Notify the pool that a QGLPixmapData object is using
+ // an texture again. This allows the pool to move the texture
+ // within a least-recently-used list of QGLPixmapData objects.
+ void useTexture(QGLPixmapData *data);
+
+ // Notify the pool that the texture associated with a
+ // QGLPixmapData is being detached from the pool. The caller
+ // will become responsible for calling glDeleteTextures().
+ void detachTexture(QGLPixmapData *data);
+
+ // Reclaim space for an image allocation with the specified parameters.
+ // Returns true if space was reclaimed, or false if there is no
+ // further space that can be reclaimed. The "data" parameter
+ // indicates the pixmap that is trying to obtain space which should
+ // not itself be reclaimed.
+ bool reclaimSpace(GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ QGLPixmapData *data);
+
+ // Hibernate the image pool because the context is about to be
+ // destroyed. All textures left in the pool should be released.
+ void hibernate();
+
+protected:
+ // Helper functions for managing the LRU list of QGLPixmapData objects.
+ void moveToHeadOfLRU(QGLPixmapData *data);
+ void removeFromLRU(QGLPixmapData *data);
+ QGLPixmapData *pixmapLRU();
+
+private:
+ QScopedPointer<QGLTexturePoolPrivate> d_ptr;
+
+ Q_DECLARE_PRIVATE(QGLTexturePool)
+ Q_DISABLE_COPY(QGLTexturePool)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index 79911fb..0aa3c2e 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -53,6 +53,14 @@
#include "private/qwindowsurface_x11gl_p.h"
#endif
+#if defined(Q_OS_SYMBIAN)
+#include <QtGui/private/qapplication_p.h>
+#endif
+
+#ifdef QGL_USE_TEXTURE_POOL
+#include "private/qgltexturepool_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
extern QGLWidget *qt_gl_getShareWidget();
@@ -86,8 +94,21 @@ QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const
}
#endif
+#if defined(Q_OS_SYMBIAN)
+ if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
+ QWidgetPrivate *d = qt_widget_private(widget);
+ if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
+ return d->createDefaultWindowSurface_sys();
+ }
+#endif
+
return new QGLWindowSurface(widget);
}
-
+#ifdef QGL_USE_TEXTURE_POOL
+void QGLGraphicsSystem::releaseCachedResources()
+{
+ QGLTexturePool::instance()->hibernate();
+}
+#endif
QT_END_NAMESPACE
diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h
index 4630da1..5829dcc 100644
--- a/src/opengl/qgraphicssystem_gl_p.h
+++ b/src/opengl/qgraphicssystem_gl_p.h
@@ -66,6 +66,10 @@ public:
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
+
+#ifdef QGL_USE_TEXTURE_POOL
+ void releaseCachedResources();
+#endif
private:
bool m_useX11GL;
};
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 43e80c1..70427d5 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -55,10 +55,11 @@
#include <qdesktopwidget.h>
#include <qfile.h>
#include <qimagereader.h>
+#include <qbuffer.h>
QT_BEGIN_NAMESPACE
-extern QGLWidget* qt_gl_share_widget();
+Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
/*!
\class QGLFramebufferObjectPool
@@ -369,40 +370,18 @@ void QGLPixmapData::ensureCreated() const
void QGLPixmapData::fromImage(const QImage &image,
Qt::ImageConversionFlags flags)
{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_gl_pixmap_serial);
- resize(image.width(), image.height());
-
- if (pixelType() == BitmapType) {
- m_source = image.convertToFormat(QImage::Format_MonoLSB);
-
- } else {
- QImage::Format format = QImage::Format_RGB32;
- if (qApp->desktop()->depth() == 16)
- format = QImage::Format_RGB16;
-
- if (image.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
- format = QImage::Format_ARGB32_Premultiplied;;
-
- m_source = image.convertToFormat(format);
- }
-
- m_dirty = true;
- m_hasFillColor = false;
+ QImage img = image;
+ createPixmapForImage(img, flags, false);
+}
- m_hasAlpha = m_source.hasAlphaChannel();
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = m_source.depth();
+void QGLPixmapData::fromImageReader(QImageReader *imageReader,
+ Qt::ImageConversionFlags flags)
+{
+ QImage image = imageReader->read();
+ if (image.isNull())
+ return;
- if (m_texture.id) {
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- }
+ createPixmapForImage(image, flags, true);
}
bool QGLPixmapData::fromFile(const QString &filename, const char *format,
@@ -411,31 +390,37 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format,
if (pixelType() == QPixmapData::BitmapType)
return QPixmapData::fromFile(filename, format, flags);
QFile file(filename);
- if (!file.open(QIODevice::ReadOnly))
- return false;
- QByteArray data = file.peek(64);
- bool alpha;
- if (m_texture.canBindCompressedTexture
- (data.constData(), data.size(), format, &alpha)) {
- resize(0, 0);
- data = file.readAll();
- file.close();
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QSize size = m_texture.bindCompressedTexture
- (data.constData(), data.size(), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QImage();
- m_dirty = isValid();
- return true;
+ if (file.open(QIODevice::ReadOnly)) {
+ QByteArray data = file.peek(64);
+ bool alpha;
+ if (m_texture.canBindCompressedTexture
+ (data.constData(), data.size(), format, &alpha)) {
+ resize(0, 0);
+ data = file.readAll();
+ file.close();
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QSize size = m_texture.bindCompressedTexture
+ (data.constData(), data.size(), format);
+ if (!size.isEmpty()) {
+ w = size.width();
+ h = size.height();
+ is_null = false;
+ d = 32;
+ m_hasAlpha = alpha;
+ m_source = QImage();
+ m_dirty = isValid();
+ return true;
+ }
+ return false;
}
- return false;
}
- fromImage(QImageReader(&file, format).read(), flags);
+
+ QImage image = QImageReader(filename, format).read();
+ if (image.isNull())
+ return false;
+
+ createPixmapForImage(image, flags, true);
+
return !isNull();
}
@@ -459,7 +444,67 @@ bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
return true;
}
}
- return QPixmapData::fromData(buffer, len, format, flags);
+
+ QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
+ QBuffer b(&a);
+ b.open(QIODevice::ReadOnly);
+ QImage image = QImageReader(&b, format).read();
+ if (image.isNull())
+ return false;
+
+ createPixmapForImage(image, flags, true);
+
+ return !isNull();
+}
+
+/*!
+ out-of-place conversion (inPlace == false) will always detach()
+ */
+void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ if (image.size() == QSize(w, h))
+ setSerialNumber(++qt_gl_pixmap_serial);
+
+ resize(image.width(), image.height());
+
+ if (pixelType() == BitmapType) {
+ m_source = image.convertToFormat(QImage::Format_MonoLSB);
+
+ } else {
+ QImage::Format format = QImage::Format_RGB32;
+ if (qApp->desktop()->depth() == 16)
+ format = QImage::Format_RGB16;
+
+ if (image.hasAlphaChannel()
+ && ((flags & Qt::NoOpaqueDetection)
+ || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
+ format = QImage::Format_ARGB32_Premultiplied;;
+
+ if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
+ m_source = image;
+ } else {
+ m_source = image.convertToFormat(format);
+
+ // convertToFormat won't detach the image if format stays the same.
+ if (image.format() == format)
+ m_source.detach();
+ }
+ }
+
+ m_dirty = true;
+ m_hasFillColor = false;
+
+ m_hasAlpha = m_source.hasAlphaChannel();
+ w = image.width();
+ h = image.height();
+ is_null = (w <= 0 || h <= 0);
+ d = m_source.depth();
+
+ if (m_texture.id) {
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ glDeleteTextures(1, &m_texture.id);
+ m_texture.id = 0;
+ }
}
bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 5545d3c..8855c20 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -59,6 +59,10 @@
#include "private/qpixmapdata_p.h"
#include "private/qglpaintdevice_p.h"
+#ifdef Q_OS_SYMBIAN
+#include "private/qvolatileimage_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
class QPaintEngine;
@@ -66,6 +70,16 @@ class QGLFramebufferObject;
class QGLFramebufferObjectFormat;
class QGLPixmapData;
+#ifdef QGL_USE_TEXTURE_POOL
+void qt_gl_register_pixmap(QGLPixmapData *pd);
+void qt_gl_unregister_pixmap(QGLPixmapData *pd);
+void qt_gl_hibernate_pixmaps();
+#endif
+
+#ifdef Q_OS_SYMBIAN
+class QNativeImageHandleProvider;
+#endif
+
class QGLFramebufferObjectPool
{
public:
@@ -107,6 +121,8 @@ public:
// Re-implemented from QPixmapData:
void resize(int width, int height);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void fromImageReader(QImageReader *imageReader,
+ Qt::ImageConversionFlags flags);
bool fromFile(const QString &filename, const char *format,
Qt::ImageConversionFlags flags);
bool fromData(const uchar *buffer, uint len, const char *format,
@@ -127,6 +143,32 @@ public:
GLuint bind(bool copyBack = true) const;
QGLTexture *texture() const;
+#ifdef QGL_USE_TEXTURE_POOL
+ void destroyTexture();
+ // Detach this image from the image pool.
+ void detachTextureFromPool();
+ // Release the GL resources associated with this pixmap and copy
+ // the pixmap's contents out of the GPU back into main memory.
+ // The GL resource will be automatically recreated the next time
+ // ensureCreated() is called. Does nothing if the pixmap cannot be
+ // hibernated for some reason (e.g. texture is shared with another
+ // process via a SgImage).
+ void hibernate();
+ // Called when the QGLTexturePool wants to reclaim this pixmap's
+ // texture objects to reuse storage.
+ void reclaimTexture();
+ void forceToImage();
+#endif
+
+#ifdef Q_OS_SYMBIAN
+ QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags);
+ void* toNativeType(NativeType type);
+ void fromNativeType(void* pixmap, NativeType type);
+ bool initFromNativeImageHandle(void *handle, const QString &type);
+ void createFromNativeImageHandleProvider();
+ void releaseNativeImageHandle();
+#endif
+
private:
bool isValid() const;
@@ -149,10 +191,19 @@ private:
QImage fillImage(const QColor &color) const;
+ void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
+
mutable QGLFramebufferObject *m_renderFbo;
mutable QPaintEngine *m_engine;
mutable QGLContext *m_ctx;
+#ifdef Q_OS_SYMBIAN
+ mutable QVolatileImage m_source;
+ mutable QNativeImageHandleProvider *nativeImageHandleProvider;
+ void *nativeImageHandle;
+ QString nativeImageType;
+#else
mutable QImage m_source;
+#endif
mutable QGLTexture m_texture;
// the texture is not in sync with the source image
@@ -167,6 +218,23 @@ private:
mutable QGLPixmapGLPaintDevice m_glDevice;
+#ifdef QGL_USE_TEXTURE_POOL
+ QGLPixmapData *nextLRU;
+ QGLPixmapData *prevLRU;
+ mutable bool inLRU;
+ mutable bool failedToAlloc;
+ mutable bool inTexturePool;
+
+ QGLPixmapData *next;
+ QGLPixmapData *prev;
+
+ friend class QGLTexturePool;
+
+ friend void qt_gl_register_pixmap(QGLPixmapData *pd);
+ friend void qt_gl_unregister_pixmap(QGLPixmapData *pd);
+ friend void qt_gl_hibernate_pixmaps();
+#endif
+
friend class QGLPixmapGLPaintDevice;
friend class QMeeGoPixmapData;
friend class QMeeGoLivePixmapData;
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp
new file mode 100644
index 0000000..95152dd
--- /dev/null
+++ b/src/opengl/qpixmapdata_poolgl.cpp
@@ -0,0 +1,936 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenGL module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixmap.h"
+#include "qglframebufferobject.h"
+
+#include <private/qpaintengine_raster_p.h>
+
+#include "qpixmapdata_gl_p.h"
+
+#include <private/qgl_p.h>
+#include <private/qdrawhelper_p.h>
+#include <private/qimage_p.h>
+#include <private/qnativeimagehandleprovider_p.h>
+
+#include <private/qpaintengineex_opengl2_p.h>
+
+#include <qdesktopwidget.h>
+#include <qfile.h>
+#include <qimagereader.h>
+#include <qbuffer.h>
+
+#include "qgltexturepool_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
+
+static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo)
+{
+ return qAbs(size.width() * size.height() - fbo->width() * fbo->height());
+}
+
+extern int qt_next_power_of_two(int v);
+
+static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz)
+{
+#ifdef QT_OPENGL_ES_2
+ QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height()));
+ if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height())
+ return rounded;
+#endif
+ return sz;
+}
+
+
+QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize)
+{
+ QGLFramebufferObject *chosen = 0;
+ QGLFramebufferObject *candidate = 0;
+ for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
+ QGLFramebufferObject *fbo = m_fbos.at(i);
+
+ if (strictSize) {
+ if (fbo->size() == requestSize && fbo->format() == requestFormat) {
+ chosen = fbo;
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ if (fbo->format() == requestFormat) {
+ // choose the fbo with a matching format and the closest size
+ if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo))
+ candidate = fbo;
+ }
+
+ if (candidate) {
+ m_fbos.removeOne(candidate);
+
+ const QSize fboSize = candidate->size();
+ QSize sz = fboSize;
+
+ if (sz.width() < requestSize.width())
+ sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5)));
+ if (sz.height() < requestSize.height())
+ sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
+
+ // wasting too much space?
+ if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
+ sz = requestSize;
+
+ if (sz != fboSize) {
+ delete candidate;
+ candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat);
+ }
+
+ chosen = candidate;
+ }
+ }
+
+ if (!chosen) {
+ if (strictSize)
+ chosen = new QGLFramebufferObject(requestSize, requestFormat);
+ else
+ chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
+ }
+
+ if (!chosen->isValid()) {
+ delete chosen;
+ chosen = 0;
+ }
+
+ return chosen;
+}
+
+void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo)
+{
+ if (fbo)
+ m_fbos << fbo;
+}
+
+
+QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const
+{
+ return data->paintEngine();
+}
+
+void QGLPixmapGLPaintDevice::beginPaint()
+{
+ if (!data->isValid())
+ return;
+
+ // QGLPaintDevice::beginPaint will store the current binding and replace
+ // it with m_thisFBO:
+ m_thisFBO = data->m_renderFbo->handle();
+ QGLPaintDevice::beginPaint();
+
+ Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2);
+
+ // QPixmap::fill() is deferred until now, where we actually need to do the fill:
+ 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);
+ }
+ else if (!data->isUninitialized()) {
+ // If the pixmap (GL Texture) has valid content (it has been
+ // 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(QRect(0, 0, data->width(), data->height()), data->bind(false));
+ }
+}
+
+void QGLPixmapGLPaintDevice::endPaint()
+{
+ if (!data->isValid())
+ return;
+
+ data->copyBackFromRenderFbo(false);
+
+ // 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
+{
+ data->ensureCreated();
+ return data->m_ctx;
+}
+
+QSize QGLPixmapGLPaintDevice::size() const
+{
+ return data->size();
+}
+
+bool QGLPixmapGLPaintDevice::alphaRequested() const
+{
+ return data->m_hasAlpha;
+}
+
+void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
+{
+ data = d;
+}
+
+int qt_gl_pixmap_serial = 0;
+
+QGLPixmapData::QGLPixmapData(PixelType type)
+ : QPixmapData(type, OpenGLClass)
+ , m_renderFbo(0)
+ , m_engine(0)
+ , m_ctx(0)
+ , nativeImageHandleProvider(0)
+ , nativeImageHandle(0)
+ , m_dirty(false)
+ , m_hasFillColor(false)
+ , m_hasAlpha(false)
+ , inLRU(false)
+ , failedToAlloc(false)
+ , inTexturePool(false)
+{
+ setSerialNumber(++qt_gl_pixmap_serial);
+ m_glDevice.setPixmapData(this);
+
+ qt_gl_register_pixmap(this);
+}
+
+QGLPixmapData::~QGLPixmapData()
+{
+ delete m_engine;
+
+ destroyTexture();
+ qt_gl_unregister_pixmap(this);
+}
+
+void QGLPixmapData::destroyTexture()
+{
+ if (inTexturePool) {
+ QGLTexturePool *pool = QGLTexturePool::instance();
+ if (m_texture.id)
+ pool->releaseTexture(this, m_texture.id);
+ } else {
+ if (m_texture.id) {
+ QGLWidget *shareWidget = qt_gl_share_widget();
+ if (shareWidget) {
+ QGLShareContextScope ctx(shareWidget->context());
+ glDeleteTextures(1, &m_texture.id);
+ }
+ }
+ }
+ m_texture.id = 0;
+ inTexturePool = false;
+
+ releaseNativeImageHandle();
+}
+
+QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
+{
+ return new QGLPixmapData(pixelType());
+}
+
+bool QGLPixmapData::isValid() const
+{
+ return w > 0 && h > 0;
+}
+
+bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
+{
+ if (ctx == m_ctx)
+ return true;
+
+ const QGLContext *share_ctx = qt_gl_share_widget()->context();
+ return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
+}
+
+void QGLPixmapData::resize(int width, int height)
+{
+ if (width == w && height == h)
+ return;
+
+ if (width <= 0 || height <= 0) {
+ width = 0;
+ height = 0;
+ }
+
+ w = width;
+ h = height;
+ is_null = (w <= 0 || h <= 0);
+ d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
+
+ destroyTexture();
+
+ m_source = QVolatileImage();
+ m_dirty = isValid();
+ setSerialNumber(++qt_gl_pixmap_serial);
+}
+
+void QGLPixmapData::ensureCreated() const
+{
+ if (!m_dirty)
+ return;
+
+ m_dirty = false;
+
+ if (nativeImageHandleProvider && !nativeImageHandle)
+ const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ m_ctx = ctx;
+
+ const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
+#ifdef QT_OPENGL_ES_2
+ const GLenum external_format = internal_format;
+#else
+ const GLenum external_format = qt_gl_preferredTextureFormat();
+#endif
+ const GLenum target = GL_TEXTURE_2D;
+
+ GLenum type = GL_UNSIGNED_BYTE;
+ // Avoid conversion when pixmap is created from CFbsBitmap of EColor64K.
+ if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16)
+ type = GL_UNSIGNED_SHORT_5_6_5;
+
+ m_texture.options &= ~QGLContext::MemoryManagedBindOption;
+
+ if (!m_texture.id) {
+ m_texture.id = QGLTexturePool::instance()->createTextureForPixmap(
+ target,
+ 0, internal_format,
+ w, h,
+ external_format,
+ type,
+ const_cast<QGLPixmapData*>(this));
+ if (!m_texture.id) {
+ failedToAlloc = true;
+ return;
+ }
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ inTexturePool = true;
+ } else if (inTexturePool) {
+ glBindTexture(target, m_texture.id);
+ QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this));
+ }
+
+ if (!m_source.isNull() && m_texture.id) {
+ if (external_format == GL_RGB) {
+ m_source.beginDataAccess();
+ QImage tx;
+ if (type == GL_UNSIGNED_BYTE)
+ tx = m_source.imageRef().convertToFormat(QImage::Format_RGB888).mirrored(false, true);
+ else if (type == GL_UNSIGNED_SHORT_5_6_5)
+ tx = m_source.imageRef().mirrored(false, true);
+ m_source.endDataAccess(true);
+
+ glBindTexture(target, m_texture.id);
+ if (!tx.isNull())
+ glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
+ type, tx.constBits());
+ else
+ qWarning("QGLPixmapData: Failed to create GL_RGB image of size %dx%d", w, h);
+ } else {
+ // do byte swizzling ARGB -> RGBA
+ m_source.beginDataAccess();
+ const QImage tx = ctx->d_func()->convertToGLFormat(m_source.imageRef(), true, external_format);
+ m_source.endDataAccess(true);
+ glBindTexture(target, m_texture.id);
+ if (!tx.isNull())
+ glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
+ type, tx.constBits());
+ else
+ qWarning("QGLPixmapData: Failed to create GL_RGBA image of size %dx%d", w, h);
+ }
+
+ if (useFramebufferObjects())
+ m_source = QVolatileImage();
+ }
+}
+
+
+void QGLPixmapData::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ QImage img = image;
+ createPixmapForImage(img, flags, false);
+}
+
+void QGLPixmapData::fromImageReader(QImageReader *imageReader,
+ Qt::ImageConversionFlags flags)
+{
+ QImage image = imageReader->read();
+ if (image.isNull())
+ return;
+
+ createPixmapForImage(image, flags, true);
+}
+
+bool QGLPixmapData::fromFile(const QString &filename, const char *format,
+ Qt::ImageConversionFlags flags)
+{
+ if (pixelType() == QPixmapData::BitmapType)
+ return QPixmapData::fromFile(filename, format, flags);
+ QFile file(filename);
+ if (file.open(QIODevice::ReadOnly)) {
+ QByteArray data = file.peek(64);
+ bool alpha;
+ if (m_texture.canBindCompressedTexture
+ (data.constData(), data.size(), format, &alpha)) {
+ resize(0, 0);
+ data = file.readAll();
+ file.close();
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QSize size = m_texture.bindCompressedTexture
+ (data.constData(), data.size(), format);
+ if (!size.isEmpty()) {
+ w = size.width();
+ h = size.height();
+ is_null = false;
+ d = 32;
+ m_hasAlpha = alpha;
+ m_source = QVolatileImage();
+ m_dirty = isValid();
+ return true;
+ }
+ return false;
+ }
+ }
+
+ QImage image = QImageReader(filename, format).read();
+ if (image.isNull())
+ return false;
+
+ createPixmapForImage(image, flags, true);
+
+ return !isNull();
+}
+
+bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
+ Qt::ImageConversionFlags flags)
+{
+ bool alpha;
+ const char *buf = reinterpret_cast<const char *>(buffer);
+ if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
+ resize(0, 0);
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
+ if (!size.isEmpty()) {
+ w = size.width();
+ h = size.height();
+ is_null = false;
+ d = 32;
+ m_hasAlpha = alpha;
+ m_source = QVolatileImage();
+ m_dirty = isValid();
+ return true;
+ }
+ }
+
+ QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
+ QBuffer b(&a);
+ b.open(QIODevice::ReadOnly);
+ QImage image = QImageReader(&b, format).read();
+ if (image.isNull())
+ return false;
+
+ createPixmapForImage(image, flags, true);
+
+ return !isNull();
+}
+
+QImage::Format QGLPixmapData::idealFormat(QImage &image, Qt::ImageConversionFlags flags)
+{
+ QImage::Format format = QImage::Format_RGB32;
+ if (qApp->desktop()->depth() == 16)
+ format = QImage::Format_RGB16;
+
+ if (image.hasAlphaChannel()
+ && ((flags & Qt::NoOpaqueDetection)
+ || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
+ format = QImage::Format_ARGB32_Premultiplied;
+
+ return format;
+}
+
+void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ if (image.size() == QSize(w, h))
+ setSerialNumber(++qt_gl_pixmap_serial);
+
+ resize(image.width(), image.height());
+
+ if (pixelType() == BitmapType) {
+ QImage convertedImage = image.convertToFormat(QImage::Format_MonoLSB);
+ if (image.format() == QImage::Format_MonoLSB)
+ convertedImage.detach();
+
+ m_source = QVolatileImage(convertedImage);
+
+ } else {
+ QImage::Format format = idealFormat(image, flags);
+
+ if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
+ m_source = QVolatileImage(image);
+ } else {
+ QImage convertedImage = image.convertToFormat(format);
+
+ // convertToFormat won't detach the image if format stays the same.
+ if (image.format() == format)
+ convertedImage.detach();
+
+ m_source = QVolatileImage(convertedImage);
+ }
+ }
+
+ m_dirty = true;
+ m_hasFillColor = false;
+
+ m_hasAlpha = m_source.hasAlphaChannel();
+ w = image.width();
+ h = image.height();
+ is_null = (w <= 0 || h <= 0);
+ d = m_source.depth();
+
+ destroyTexture();
+}
+
+bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
+{
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
+ Q_UNUSED(rect);
+ return false;
+}
+
+void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
+ QPixmapData::copy(data, rect);
+ return;
+ }
+
+ const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
+ if (other->m_renderFbo) {
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+
+ resize(rect.width(), rect.height());
+ m_hasAlpha = other->m_hasAlpha;
+ ensureCreated();
+
+ if (!ctx->d_ptr->fbo)
+ glGenFramebuffers(1, &ctx->d_ptr->fbo);
+
+ 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);
+
+ if (!other->m_renderFbo->isBound())
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());
+
+ glDisable(GL_SCISSOR_TEST);
+ if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
+ static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();
+
+ glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
+ 0, 0, w, h,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
+ } else {
+ QPixmapData::copy(data, rect);
+ }
+}
+
+void QGLPixmapData::fill(const QColor &color)
+{
+ if (!isValid())
+ return;
+
+ bool hasAlpha = color.alpha() != 255;
+ if (hasAlpha && !m_hasAlpha) {
+ if (m_texture.id) {
+ destroyTexture();
+ m_dirty = true;
+ }
+ m_hasAlpha = color.alpha() != 255;
+ }
+
+ if (useFramebufferObjects()) {
+ m_source = QVolatileImage();
+ m_hasFillColor = true;
+ m_fillColor = color;
+ } else {
+ forceToImage();
+
+ if (m_source.depth() == 32) {
+ m_source.fill(PREMUL(color.rgba()));
+
+ } else if (m_source.depth() == 1) {
+ if (color == Qt::color1)
+ m_source.fill(1);
+ else
+ m_source.fill(0);
+ }
+ }
+}
+
+bool QGLPixmapData::hasAlphaChannel() const
+{
+ return m_hasAlpha;
+}
+
+QImage QGLPixmapData::fillImage(const QColor &color) const
+{
+ QImage img;
+ if (pixelType() == BitmapType) {
+ img = QImage(w, h, QImage::Format_MonoLSB);
+
+ img.setColorCount(2);
+ img.setColor(0, QColor(Qt::color0).rgba());
+ img.setColor(1, QColor(Qt::color1).rgba());
+
+ if (color == Qt::color1)
+ img.fill(1);
+ else
+ img.fill(0);
+ } else {
+ img = QImage(w, h,
+ m_hasAlpha
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32);
+ img.fill(PREMUL(color.rgba()));
+ }
+ return img;
+}
+
+extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
+
+QImage QGLPixmapData::toImage() const
+{
+ if (!isValid())
+ return QImage();
+
+ if (m_renderFbo) {
+ copyBackFromRenderFbo(true);
+ } else if (!m_source.isNull()) {
+ // QVolatileImage::toImage() will make a copy always so no check
+ // for active painting is needed.
+ QImage img = m_source.toImage();
+ if (img.format() == QImage::Format_MonoLSB) {
+ img.setColorCount(2);
+ img.setColor(0, QColor(Qt::color0).rgba());
+ img.setColor(1, QColor(Qt::color1).rgba());
+ }
+ return img;
+ } else if (m_dirty || m_hasFillColor) {
+ return fillImage(m_fillColor);
+ } else {
+ ensureCreated();
+ }
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ glBindTexture(GL_TEXTURE_2D, m_texture.id);
+ return qt_gl_read_texture(QSize(w, h), true, true);
+}
+
+struct TextureBuffer
+{
+ QGLFramebufferObject *fbo;
+ QGL2PaintEngineEx *engine;
+};
+
+Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool)
+QGLFramebufferObjectPool* qgl_fbo_pool()
+{
+ return _qgl_fbo_pool();
+}
+
+void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
+{
+ if (!isValid())
+ return;
+
+ m_hasFillColor = false;
+
+ const QGLContext *share_ctx = qt_gl_share_widget()->context();
+ QGLShareContextScope ctx(share_ctx);
+
+ ensureCreated();
+
+ if (!ctx->d_ptr->fbo)
+ glGenFramebuffers(1, &ctx->d_ptr->fbo);
+
+ 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;
+ const int x1 = w;
+ const int y0 = 0;
+ const int y1 = h;
+
+ if (!m_renderFbo->isBound())
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
+
+ glDisable(GL_SCISSOR_TEST);
+
+ glBlitFramebufferEXT(x0, y0, x1, y1,
+ x0, y0, x1, y1,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+
+ if (keepCurrentFboBound) {
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
+ } else {
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
+ ctx->d_ptr->current_fbo = m_renderFbo->handle();
+ }
+}
+
+bool QGLPixmapData::useFramebufferObjects() const
+{
+#ifdef Q_OS_SYMBIAN
+ // We don't want to use FBOs on Symbian
+ return false;
+#else
+ return QGLFramebufferObject::hasOpenGLFramebufferObjects()
+ && QGLFramebufferObject::hasOpenGLFramebufferBlit()
+ && qt_gl_preferGL2Engine()
+ && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
+#endif
+}
+
+QPaintEngine* QGLPixmapData::paintEngine() const
+{
+ if (!isValid())
+ return 0;
+
+ if (m_renderFbo)
+ return m_engine;
+
+ if (useFramebufferObjects()) {
+ extern QGLWidget* qt_gl_share_widget();
+
+ if (!QGLContext::currentContext())
+ qt_gl_share_widget()->makeCurrent();
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+
+ QGLFramebufferObjectFormat format;
+ format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
+ format.setSamples(4);
+ format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));
+
+ m_renderFbo = qgl_fbo_pool()->acquire(size(), format);
+
+ if (m_renderFbo) {
+ if (!m_engine)
+ m_engine = new QGL2PaintEngineEx;
+ return m_engine;
+ }
+
+ qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
+ }
+
+ // If the application wants to paint into the QPixmap, we first
+ // force it to QImage format and then paint into that.
+ // This is simpler than juggling multiple GL contexts.
+ const_cast<QGLPixmapData *>(this)->forceToImage();
+
+ if (m_hasFillColor) {
+ m_source.fill(PREMUL(m_fillColor.rgba()));
+ m_hasFillColor = false;
+ }
+ return m_source.paintEngine();
+}
+
+extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
+
+// If copyBack is true, bind will copy the contents of the render
+// FBO to the texture (which is not bound to the texture, as it's
+// a multisample FBO).
+GLuint QGLPixmapData::bind(bool copyBack) const
+{
+ if (m_renderFbo && copyBack) {
+ copyBackFromRenderFbo(true);
+ } else {
+ ensureCreated();
+ }
+
+ GLuint id = m_texture.id;
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ if (m_hasFillColor) {
+ if (!useFramebufferObjects()) {
+ m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
+ m_source.fill(PREMUL(m_fillColor.rgba()));
+ }
+
+ m_hasFillColor = false;
+
+ GLenum format = qt_gl_preferredTextureFormat();
+ QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
+ tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits());
+ }
+
+ return id;
+}
+
+QGLTexture* QGLPixmapData::texture() const
+{
+ return &m_texture;
+}
+
+void QGLPixmapData::detachTextureFromPool()
+{
+ if (inTexturePool) {
+ QGLTexturePool::instance()->detachTexture(this);
+ inTexturePool = false;
+ }
+}
+
+void QGLPixmapData::hibernate()
+{
+ // If the image was imported (e.g, from an SgImage under Symbian), then
+ // skip the hibernation, there is no sense in copying it back to main
+ // memory because the data is most likely shared between several processes.
+ bool skipHibernate = (m_texture.id && m_source.isNull());
+#if defined(Q_OS_SYMBIAN)
+ // However we have to proceed normally if the image was retrieved via
+ // a handle provider.
+ skipHibernate &= !nativeImageHandleProvider;
+#endif
+ if (skipHibernate)
+ return;
+
+ forceToImage();
+ destroyTexture();
+}
+
+void QGLPixmapData::reclaimTexture()
+{
+ if (!inTexturePool)
+ return;
+ forceToImage();
+ destroyTexture();
+}
+
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
+
+int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ if (w == 0)
+ return 0;
+
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return w;
+ case QPaintDevice::PdmHeight:
+ return h;
+ case QPaintDevice::PdmNumColors:
+ return 0;
+ case QPaintDevice::PdmDepth:
+ return d;
+ case QPaintDevice::PdmWidthMM:
+ return qRound(w * 25.4 / qt_defaultDpiX());
+ case QPaintDevice::PdmHeightMM:
+ return qRound(h * 25.4 / qt_defaultDpiY());
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ return qt_defaultDpiX();
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ return qt_defaultDpiY();
+ default:
+ qWarning("QGLPixmapData::metric(): Invalid metric");
+ return 0;
+ }
+}
+
+// Force the pixmap data to be backed by some valid data.
+void QGLPixmapData::forceToImage()
+{
+ if (!isValid())
+ return;
+
+ if (m_source.isNull()) {
+ QImage::Format format = QImage::Format_ARGB32_Premultiplied;
+ if (pixelType() == BitmapType)
+ format = QImage::Format_MonoLSB;
+ m_source = QVolatileImage(w, h, format);
+ }
+
+ m_dirty = true;
+}
+
+QGLPaintDevice *QGLPixmapData::glDevice() const
+{
+ return &m_glDevice;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index aad12d7..b056caa 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -181,16 +181,14 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
//
// QGLWindowSurface
//
-
class QGLGlobalShareWidget
{
public:
- QGLGlobalShareWidget() : widget(0), initializing(false) {}
+ QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {}
QGLWidget *shareWidget() {
if (!initializing && !widget && !cleanedUp) {
initializing = true;
-
widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer));
widget->resize(1, 1);
@@ -226,6 +224,9 @@ public:
static bool cleanedUp;
+ QGLPixmapData *firstPixmap;
+ int widgetRefCount;
+
private:
QGLWidget *widget;
bool initializing;
@@ -256,6 +257,43 @@ void qt_destroy_gl_share_widget()
_qt_gl_share_widget()->destroy();
}
+#ifdef QGL_USE_TEXTURE_POOL
+void qt_gl_register_pixmap(QGLPixmapData *pd)
+{
+ QGLGlobalShareWidget *shared = _qt_gl_share_widget();
+ pd->next = shared->firstPixmap;
+ pd->prev = 0;
+ if (shared->firstPixmap)
+ shared->firstPixmap->prev = pd;
+ shared->firstPixmap = pd;
+}
+
+void qt_gl_unregister_pixmap(QGLPixmapData *pd)
+{
+ if (pd->next)
+ pd->next->prev = pd->prev;
+ if (pd->prev) {
+ pd->prev->next = pd->next;
+ } else {
+ QGLGlobalShareWidget *shared = _qt_gl_share_widget();
+ if (shared)
+ shared->firstPixmap = pd->next;
+ }
+}
+
+void qt_gl_hibernate_pixmaps()
+{
+ QGLGlobalShareWidget *shared = _qt_gl_share_widget();
+
+ // Scan all QGLPixmapData objects in the system and hibernate them.
+ QGLPixmapData *pd = shared->firstPixmap;
+ while (pd != 0) {
+ pd->hibernate();
+ pd = pd->next;
+ }
+}
+#endif
+
struct QGLWindowSurfacePrivate
{
QGLFramebufferObject *fbo;
@@ -333,6 +371,10 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window)
d_ptr->q_ptr = this;
d_ptr->geometry_updated = false;
d_ptr->did_paint = false;
+
+#ifdef QGL_NO_PRESERVED_SWAP
+ setPartialUpdateSupport(false);
+#endif
}
QGLWindowSurface::~QGLWindowSurface()
@@ -347,6 +389,27 @@ QGLWindowSurface::~QGLWindowSurface()
delete d_ptr->pb;
delete d_ptr->fbo;
delete d_ptr;
+
+ if (QGLGlobalShareWidget::cleanedUp)
+ return;
+
+ --(_qt_gl_share_widget()->widgetRefCount);
+
+#ifdef QGL_USE_TEXTURE_POOL
+ if (_qt_gl_share_widget()->widgetRefCount <= 0) {
+ // All of the widget window surfaces have been destroyed
+ // but we still have GL pixmaps active. Ask them to hibernate
+ // to free up GPU resources until a widget is shown again.
+ // This may eventually cause the EGLContext to be destroyed
+ // because nothing in the system needs a context, which will
+ // free up even more GPU resources.
+ qt_gl_hibernate_pixmaps();
+
+ // Destroy the context if necessary.
+ if (!qt_gl_share_widget()->context()->isSharing())
+ qt_destroy_gl_share_widget();
+ }
+#endif
}
void QGLWindowSurface::deleted(QObject *object)
@@ -394,6 +457,9 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
ctx->create(qt_gl_share_widget()->context());
+ if (widget != qt_gl_share_widget())
+ ++(_qt_gl_share_widget()->widgetRefCount);
+
#ifndef QT_NO_EGL
static bool checkedForNOKSwapRegion = false;
static bool haveNOKSwapRegion = false;
@@ -406,8 +472,16 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
}
- if (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED &&
- ! haveNOKSwapRegion)
+ bool swapBehaviourPreserved = ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR);
+ if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
+ EGLint swapBehavior;
+ if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface
+ , EGL_SWAP_BEHAVIOR, &swapBehavior)) {
+ swapBehaviourPreserved = (swapBehavior == EGL_BUFFER_PRESERVED);
+ }
+ }
+
+ if (!swapBehaviourPreserved && !haveNOKSwapRegion)
setPartialUpdateSupport(false); // Force full-screen updates
else
setPartialUpdateSupport(true);
@@ -421,7 +495,9 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
voidPtr = &widgetPrivate->extraData()->glContext;
d_ptr->contexts << ctxPtr;
+#ifndef Q_OS_SYMBIAN
qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
+#endif
}
QGLContext *QGLWindowSurface::context() const
@@ -450,6 +526,8 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
void QGLWindowSurface::beginPaint(const QRegion &)
{
+ updateGeometry();
+
if (!context())
return;
@@ -628,7 +706,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
} else {
glFlush();
}
-
return;
}
@@ -776,32 +853,53 @@ void QGLWindowSurface::updateGeometry() {
return;
d_ptr->geometry_updated = false;
- QRect rect = geometry();
- hijackWindow(window());
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
+ bool hijack(true);
+ QWidgetPrivate *wd = window()->d_func();
+ if (wd->extraData() && wd->extraData()->glContext) {
+#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
+ if (d_ptr->size != geometry().size()) {
+ if (window() != qt_gl_share_widget())
+ --(_qt_gl_share_widget()->widgetRefCount);
+
+ delete wd->extraData()->glContext;
+ wd->extraData()->glContext = 0;
+ d_ptr->ctx = 0;
+ }
+ else
+#endif
+ {
+ hijack = false; // we already have gl context for widget
+ }
+ }
+
+ if (hijack)
+ hijackWindow(window());
+
+ QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
#ifdef Q_WS_MAC
ctx->updatePaintDevice();
#endif
- const GLenum target = GL_TEXTURE_2D;
+ QSize surfSize = geometry().size();
- if (rect.width() <= 0 || rect.height() <= 0)
+ if (surfSize.width() <= 0 || surfSize.height() <= 0)
return;
- if (d_ptr->size == rect.size())
+ if (d_ptr->size == surfSize)
return;
- d_ptr->size = rect.size();
+ d_ptr->size = surfSize;
if (d_ptr->ctx) {
#ifndef QT_OPENGL_ES_2
if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(rect.size());
+ initializeOffscreenTexture(surfSize);
#endif
return;
}
+ const GLenum target = GL_TEXTURE_2D;
if (d_ptr->destructive_swap_buffers
&& (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject)
&& (d_ptr->fbo || !d_ptr->tried_fbo)
@@ -820,10 +918,10 @@ void QGLWindowSurface::updateGeometry() {
if (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)
format.setSamples(8);
- d_ptr->fbo = new QGLFramebufferObject(rect.size(), format);
+ d_ptr->fbo = new QGLFramebufferObject(surfSize, format);
if (d_ptr->fbo->isValid()) {
- qDebug() << "Created Window Surface FBO" << rect.size()
+ qDebug() << "Created Window Surface FBO" << surfSize
<< "with samples" << d_ptr->fbo->format().samples();
return;
} else {
@@ -844,7 +942,7 @@ void QGLWindowSurface::updateGeometry() {
delete d_ptr->pb;
- d_ptr->pb = new QGLPixelBuffer(rect.width(), rect.height(),
+ d_ptr->pb = new QGLPixelBuffer(surfSize.width(), surfSize.height(),
QGLFormat(QGL::SampleBuffers | QGL::StencilBuffer | QGL::DepthBuffer),
qt_gl_share_widget());
@@ -854,7 +952,7 @@ void QGLWindowSurface::updateGeometry() {
glGenTextures(1, &d_ptr->pb_tex_id);
glBindTexture(target, d_ptr->pb_tex_id);
- glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glTexImage2D(target, 0, GL_RGBA, surfSize.width(), surfSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -878,10 +976,11 @@ void QGLWindowSurface::updateGeometry() {
#ifndef QT_OPENGL_ES_2
if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(rect.size());
+ initializeOffscreenTexture(surfSize);
+#endif
+#ifndef Q_OS_SYMBIAN
+ qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;
#endif
-
- qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;;
d_ptr->ctx = ctx;
d_ptr->ctx->d_ptr->internal_context = true;
}
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 22cbbf5..ebdfa5f 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -1024,9 +1024,11 @@ static VGImage toVGImage
switch (img.format()) {
case QImage::Format_Mono:
img = image.convertToFormat(QImage::Format_MonoLSB, flags);
+ img.invertPixels();
format = VG_BW_1;
break;
case QImage::Format_MonoLSB:
+ img.invertPixels();
format = VG_BW_1;
break;
case QImage::Format_RGB32:
@@ -2333,6 +2335,7 @@ bool QVGPaintEngine::isDefaultClipRect(const QRect& rect)
void QVGPaintEngine::clipEnabledChanged()
{
#if defined(QVG_SCISSOR_CLIP)
+ vgSeti(VG_MASKING, VG_FALSE); // disable mask fallback
updateScissor();
#else
Q_D(QVGPaintEngine);
@@ -3070,6 +3073,95 @@ static void drawVGImage(QVGPaintEnginePrivate *d,
vgDrawImage(vgImg);
}
+static void drawImageTiled(QVGPaintEnginePrivate *d,
+ const QRectF &r,
+ const QImage &image,
+ const QRectF &sr = QRectF())
+{
+ const int minTileSize = 16;
+ int tileWidth = 512;
+ int tileHeight = tileWidth;
+
+ VGImageFormat tileFormat = qt_vg_image_to_vg_format(image.format());
+ VGImage tile = VG_INVALID_HANDLE;
+ QVGImagePool *pool = QVGImagePool::instance();
+ while (tile == VG_INVALID_HANDLE && tileWidth >= minTileSize) {
+ tile = pool->createPermanentImage(tileFormat, tileWidth, tileHeight,
+ VG_IMAGE_QUALITY_FASTER);
+ if (tile == VG_INVALID_HANDLE) {
+ tileWidth /= 2;
+ tileHeight /= 2;
+ }
+ }
+ if (tile == VG_INVALID_HANDLE) {
+ qWarning("drawImageTiled: Failed to create %dx%d tile, giving up", tileWidth, tileHeight);
+ return;
+ }
+
+ VGfloat opacityMatrix[20] = {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, d->opacity,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ };
+ VGImage tileWithOpacity = VG_INVALID_HANDLE;
+ if (d->opacity != 1) {
+ tileWithOpacity = pool->createPermanentImage(VG_sARGB_8888_PRE,
+ tileWidth, tileHeight, VG_IMAGE_QUALITY_FASTER);
+ if (tileWithOpacity == VG_INVALID_HANDLE)
+ qWarning("drawImageTiled: Failed to create extra tile, ignoring opacity");
+ }
+
+ QRect sourceRect = sr.toRect();
+ if (sourceRect.isNull())
+ sourceRect = QRect(0, 0, image.width(), image.height());
+
+ VGfloat scaleX = r.width() / sourceRect.width();
+ VGfloat scaleY = r.height() / sourceRect.height();
+
+ d->setImageOptions();
+
+ for (int y = sourceRect.y(); y < sourceRect.height(); y += tileHeight) {
+ int h = qMin(tileHeight, sourceRect.height() - y);
+ if (h < 1)
+ break;
+ for (int x = sourceRect.x(); x < sourceRect.width(); x += tileWidth) {
+ int w = qMin(tileWidth, sourceRect.width() - x);
+ if (w < 1)
+ break;
+
+ int bytesPerPixel = image.depth() / 8;
+ const uchar *sptr = image.constBits() + x * bytesPerPixel + y * image.bytesPerLine();
+ vgImageSubData(tile, sptr, image.bytesPerLine(), tileFormat, 0, 0, w, h);
+
+ QTransform transform(d->imageTransform);
+ transform.translate(r.x() + x, r.y() + y);
+ transform.scale(scaleX, scaleY);
+ d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
+
+ VGImage actualTile = tile;
+ if (tileWithOpacity != VG_INVALID_HANDLE) {
+ vgColorMatrix(tileWithOpacity, actualTile, opacityMatrix);
+ if (w < tileWidth || h < tileHeight)
+ actualTile = vgChildImage(tileWithOpacity, 0, 0, w, h);
+ else
+ actualTile = tileWithOpacity;
+ } else if (w < tileWidth || h < tileHeight) {
+ actualTile = vgChildImage(tile, 0, 0, w, h);
+ }
+ vgDrawImage(actualTile);
+
+ if (actualTile != tile && actualTile != tileWithOpacity)
+ vgDestroyImage(actualTile);
+ }
+ }
+
+ vgDestroyImage(tile);
+ if (tileWithOpacity != VG_INVALID_HANDLE)
+ vgDestroyImage(tileWithOpacity);
+}
+
// Used by qpixmapfilter_vg.cpp to draw filtered VGImage's.
void qt_vg_drawVGImage(QPainter *painter, const QPointF& pos, VGImage vgImg)
{
@@ -3099,6 +3191,19 @@ void qt_vg_drawVGImageStencil
bool QVGPaintEngine::canVgWritePixels(const QImage &image) const
{
Q_D(const QVGPaintEngine);
+
+ // qt_vg_image_to_vg_format returns VG_sARGB_8888 as
+ // fallback case if no matching VG format is found.
+ // If given image format is not Format_ARGB32 and returned
+ // format is VG_sARGB_8888, it means that no match was
+ // found. In that case vgWritePixels cannot be used.
+ // Also 1-bit formats cannot be used directly either.
+ if ((image.format() != QImage::Format_ARGB32
+ && qt_vg_image_to_vg_format(image.format()) == VG_sARGB_8888)
+ || image.depth() == 1) {
+ return false;
+ }
+
// vgWritePixels ignores masking, blending and xforms so we can only use it if
// ALL of the following conditions are true:
// - It is a simple translate, or a scale of -1 on the y-axis (inverted)
@@ -3134,9 +3239,13 @@ void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ vgpd->source.beginDataAccess();
+ drawImage(r, vgpd->source.imageRef(), sr, Qt::AutoColor);
+ vgpd->source.endDataAccess(true);
+ } else {
+ drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ }
}
void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
@@ -3162,9 +3271,13 @@ void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(pos, *(pd->buffer()));
+ vgpd->source.beginDataAccess();
+ drawImage(pos, vgpd->source.imageRef());
+ vgpd->source.endDataAccess(true);
+ } else {
+ drawImage(pos, *(pd->buffer()));
+ }
}
void QVGPaintEngine::drawImage
@@ -3172,6 +3285,8 @@ void QVGPaintEngine::drawImage
Qt::ImageConversionFlags flags)
{
Q_D(QVGPaintEngine);
+ if (image.isNull())
+ return;
VGImage vgImg;
if (d->simpleTransform || d->opacity == 1.0f)
vgImg = toVGImageSubRect(image, sr.toRect(), flags);
@@ -3208,7 +3323,10 @@ void QVGPaintEngine::drawImage
} else {
// Monochrome images need to use the vgChildImage() path.
vgImg = toVGImage(image, flags);
- drawVGImage(d, r, vgImg, image.size(), sr);
+ if (vgImg == VG_INVALID_HANDLE)
+ drawImageTiled(d, r, image, sr);
+ else
+ drawVGImage(d, r, vgImg, image.size(), sr);
}
}
vgDestroyImage(vgImg);
@@ -3217,6 +3335,8 @@ void QVGPaintEngine::drawImage
void QVGPaintEngine::drawImage(const QPointF &pos, const QImage &image)
{
Q_D(QVGPaintEngine);
+ if (image.isNull())
+ return;
VGImage vgImg;
if (canVgWritePixels(image)) {
// Optimization for straight blits, no blending
@@ -3233,7 +3353,10 @@ void QVGPaintEngine::drawImage(const QPointF &pos, const QImage &image)
} else {
vgImg = toVGImageWithOpacity(image, d->opacity);
}
- drawVGImage(d, pos, vgImg);
+ if (vgImg == VG_INVALID_HANDLE)
+ drawImageTiled(d, QRectF(pos, image.size()), image);
+ else
+ drawVGImage(d, pos, vgImg);
vgDestroyImage(vgImg);
}
@@ -4010,6 +4133,8 @@ VGImageFormat qt_vg_image_to_vg_format(QImage::Format format)
switch (format) {
case QImage::Format_MonoLSB:
return VG_BW_1;
+ case QImage::Format_Indexed8:
+ return VG_sL_8;
case QImage::Format_ARGB32_Premultiplied:
return VG_sARGB_8888_PRE;
case QImage::Format_RGB32:
@@ -4020,7 +4145,8 @@ VGImageFormat qt_vg_image_to_vg_format(QImage::Format format)
return VG_sRGB_565;
case QImage::Format_ARGB4444_Premultiplied:
return VG_sARGB_4444;
- default: break;
+ default:
+ break;
}
return VG_sARGB_8888; // XXX
}
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index 85583cc..1e9103b 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QFixedPoint;
+struct QFixedPoint;
class QVGPaintEnginePrivate;
class QPixmapData;
class QVGEGLWindowSurfacePrivate;
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 732b484..80f5b2f 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -50,6 +50,7 @@
#include <QBuffer>
#include <QImageReader>
#include <QtGui/private/qimage_p.h>
+#include <QtGui/private/qnativeimagehandleprovider_p.h>
QT_BEGIN_NAMESPACE
@@ -66,11 +67,15 @@ QVGPixmapData::QVGPixmapData(PixelType type)
inImagePool = false;
inLRU = false;
failedToAlloc = false;
+#if defined(Q_OS_SYMBIAN)
+ nativeImageHandleProvider = 0;
+ nativeImageHandle = 0;
+#endif
#if !defined(QT_NO_EGL)
context = 0;
qt_vg_register_pixmap(this);
#endif
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
QVGPixmapData::~QVGPixmapData()
@@ -98,6 +103,10 @@ void QVGPixmapData::destroyImages()
vgImage = VG_INVALID_HANDLE;
vgImageOpacity = VG_INVALID_HANDLE;
inImagePool = false;
+
+#if defined(Q_OS_SYMBIAN)
+ releaseNativeImageHandle();
+#endif
}
void QVGPixmapData::destroyImageAndContext()
@@ -105,6 +114,8 @@ void QVGPixmapData::destroyImageAndContext()
if (vgImage != VG_INVALID_HANDLE) {
// We need to have a context current to destroy the image.
#if !defined(QT_NO_EGL)
+ if (!context)
+ context = qt_vg_create_context(0, QInternal::Pixmap);
if (context->isCurrent()) {
destroyImages();
} else {
@@ -118,6 +129,10 @@ void QVGPixmapData::destroyImageAndContext()
#else
destroyImages();
#endif
+ } else {
+#if defined(Q_OS_SYMBIAN)
+ releaseNativeImageHandle();
+#endif
}
#if !defined(QT_NO_EGL)
if (context) {
@@ -138,25 +153,31 @@ bool QVGPixmapData::isValid() const
return (w > 0 && h > 0);
}
+void QVGPixmapData::updateSerial()
+{
+ setSerialNumber(++qt_vg_pixmap_serial);
+}
+
void QVGPixmapData::resize(int wid, int ht)
{
- if (w == wid && h == ht)
+ if (w == wid && h == ht) {
+ updateSerial();
return;
+ }
w = wid;
h = ht;
d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
is_null = (w <= 0 || h <= 0);
- source = QImage();
+ source = QVolatileImage();
recreate = true;
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
-void QVGPixmapData::fromImage
- (const QImage &image, Qt::ImageConversionFlags flags)
+void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
- if(image.isNull())
+ if (image.isNull())
return;
QImage img = image;
@@ -200,33 +221,34 @@ bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
return !isNull();
}
-/*!
- out-of-place conversion (inPlace == false) will always detach()
- */
-void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_vg_pixmap_serial);
- else
- resize(image.width(), image.height());
-
QImage::Format format = sourceFormat();
- int d = image.depth();
- if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel()))
+ int d = image->depth();
+ if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
format = QImage::Format_RGB32;
- else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())
+ else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
format = sourceFormat();
else
- format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ return format;
+}
+
+void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ resize(image.width(), image.height());
+
+ QImage::Format format = idealFormat(&image, flags);
if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- source = image;
+ source = QVolatileImage(image);
} else {
- source = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- source.detach();
+ QImage convertedImage = image.convertToFormat(format);
+ // convertToFormat won't detach the image if format stays the
+ // same. Detaching is needed to prevent issues with painting
+ // onto this QPixmap later on.
+ convertedImage.detach();
+ source = QVolatileImage(convertedImage);
}
recreate = true;
@@ -236,27 +258,23 @@ void QVGPixmapData::fill(const QColor &color)
{
if (!isValid())
return;
-
- if (source.isNull())
- source = QImage(w, h, sourceFormat());
-
+ forceToImage();
if (source.depth() == 1) {
// Pick the best approximate color in the image's colortable.
int gray = qGray(color.rgba());
- if (qAbs(qGray(source.color(0)) - gray) < qAbs(qGray(source.color(1)) - gray))
+ if (qAbs(qGray(source.imageRef().color(0)) - gray)
+ < qAbs(qGray(source.imageRef().color(1)) - gray))
source.fill(0);
else
source.fill(1);
} else {
source.fill(PREMUL(color.rgba()));
}
-
- // Re-upload the image to VG the next time toVGImage() is called.
- recreate = true;
}
bool QVGPixmapData::hasAlphaChannel() const
{
+ ensureReadback(true);
if (!source.isNull())
return source.hasAlphaChannel();
else
@@ -265,27 +283,52 @@ bool QVGPixmapData::hasAlphaChannel() const
void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
{
+ if (!isValid())
+ return;
forceToImage();
- source.setAlphaChannel(alphaChannel.toImage());
+ source.setAlphaChannel(alphaChannel);
}
QImage QVGPixmapData::toImage() const
{
if (!isValid())
return QImage();
-
+ ensureReadback(true);
if (source.isNull()) {
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
+ return source.toImage();
+}
- return source;
+void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ // toImage() is potentially expensive with QVolatileImage so provide a
+ // more efficient implementation of copy() that does not rely on it.
+ if (!data) {
+ return;
+ }
+ if (data->classId() != OpenVGClass) {
+ fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
+ return;
+ }
+ const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
+ QRect r = rect;
+ if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
+ r = QRect(0, 0, pd->w, pd->h);
+ }
+ resize(r.width(), r.height());
+ recreate = true;
+ if (!pd->source.isNull()) {
+ source = QVolatileImage(r.width(), r.height(), pd->source.format());
+ source.copyFrom(&pd->source, r);
+ }
}
QImage *QVGPixmapData::buffer()
{
- forceToImage();
- return &source;
+ // Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
+ return 0;
}
QPaintEngine* QVGPixmapData::paintEngine() const
@@ -313,6 +356,12 @@ VGImage QVGPixmapData::toVGImage()
else if (recreate)
cachedOpacity = -1.0f; // Force opacity image to be refreshed later.
+#if defined(Q_OS_SYMBIAN)
+ if (recreate && nativeImageHandleProvider && !nativeImageHandle) {
+ createFromNativeImageHandleProvider();
+ }
+#endif
+
if (vgImage == VG_INVALID_HANDLE) {
vgImage = QVGImagePool::instance()->createImageForPixmap
(qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);
@@ -329,10 +378,12 @@ VGImage QVGPixmapData::toVGImage()
}
if (!source.isNull() && recreate) {
+ source.beginDataAccess();
vgImageSubData
(vgImage,
source.constBits(), source.bytesPerLine(),
qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
+ source.endDataAccess(true);
}
recreate = false;
@@ -395,12 +446,19 @@ void QVGPixmapData::detachImageFromPool()
void QVGPixmapData::hibernate()
{
- // If the image was imported (e.g, from an SgImage under Symbian),
- // then we cannot copy it back to main memory for storage.
- if (vgImage != VG_INVALID_HANDLE && source.isNull())
+ // If the image was imported (e.g, from an SgImage under Symbian), then
+ // skip the hibernation, there is no sense in copying it back to main
+ // memory because the data is most likely shared between several processes.
+ bool skipHibernate = (vgImage != VG_INVALID_HANDLE && source.isNull());
+#if defined(Q_OS_SYMBIAN)
+ // However we have to proceed normally if the image was retrieved via
+ // a handle provider.
+ skipHibernate &= !nativeImageHandleProvider;
+#endif
+ if (skipHibernate)
return;
- forceToImage();
+ forceToImage(false); // no readback allowed here
destroyImageAndContext();
}
@@ -442,18 +500,48 @@ int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
}
}
-// Force the pixmap data to be in QImage format.
-void QVGPixmapData::forceToImage()
+// Ensures that the pixmap is backed by some valid data and forces the data to
+// be re-uploaded to the VGImage when toVGImage() is called next time.
+void QVGPixmapData::forceToImage(bool allowReadback)
{
if (!isValid())
return;
+ if (allowReadback)
+ ensureReadback(false);
+
if (source.isNull())
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
+void QVGPixmapData::ensureReadback(bool readOnly) const
+{
+ if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
+ source = QVolatileImage(w, h, sourceFormat());
+ source.beginDataAccess();
+ vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
+ qt_vg_image_to_vg_format(source.format()),
+ 0, 0, w, h);
+ source.endDataAccess();
+ if (readOnly) {
+ recreate = false;
+ } else {
+ // Once we did a readback, the original VGImage must be destroyed
+ // because it may be shared (e.g. created via SgImage) and a subsequent
+ // upload of the image data may produce unexpected results.
+ const_cast<QVGPixmapData *>(this)->destroyImages();
+#if defined(Q_OS_SYMBIAN)
+ // There is now an own copy of the data so drop the handle provider,
+ // otherwise toVGImage() would request the handle again, which is wrong.
+ nativeImageHandleProvider = 0;
+#endif
+ recreate = true;
+ }
+ }
+}
+
QImage::Format QVGPixmapData::sourceFormat() const
{
return QImage::Format_ARGB32_Premultiplied;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index 58e69db..c284596 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -54,7 +54,8 @@
//
#include <QtGui/private/qpixmap_raster_p.h>
-#include <private/qvg_p.h>
+#include <QtGui/private/qvolatileimage_p.h>
+#include "qvg_p.h"
#if defined(Q_OS_SYMBIAN)
class RSGImage;
@@ -75,6 +76,8 @@ void qt_vg_unregister_pixmap(QVGPixmapData *pd);
void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
#endif
+class QNativeImageHandleProvider;
+
class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData
{
public:
@@ -99,6 +102,7 @@ public:
bool hasAlphaChannel() const;
void setAlphaChannel(const QPixmap &alphaChannel);
QImage toImage() const;
+ void copy(const QPixmapData *data, const QRect &rect);
QImage *buffer();
QPaintEngine* paintEngine() const;
@@ -124,11 +128,21 @@ public:
// VGImage objects to reuse storage.
virtual void reclaimImages();
+ // If vgImage is valid but source is null, copies pixel data from GPU back
+ // into main memory and destroys vgImage. For a normal pixmap this function
+ // does nothing, however if the pixmap was created directly from a VGImage
+ // (e.g. via SgImage on Symbian) then by doing the readback this ensures
+ // that QImage-based functions can operate too.
+ virtual void ensureReadback(bool readOnly) const;
+
QSize size() const { return QSize(w, h); }
#if defined(Q_OS_SYMBIAN)
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
+ bool initFromNativeImageHandle(void *handle, const QString &type);
+ void createFromNativeImageHandleProvider();
+ void releaseNativeImageHandle();
#endif
protected:
@@ -161,15 +175,23 @@ protected:
VGImage vgImage;
VGImage vgImageOpacity;
qreal cachedOpacity;
- mutable QImage source;
+ mutable QVolatileImage source;
mutable bool recreate;
bool inImagePool;
#if !defined(QT_NO_EGL)
mutable QEglContext *context;
#endif
- void forceToImage();
+#if defined(Q_OS_SYMBIAN)
+ mutable QNativeImageHandleProvider *nativeImageHandleProvider;
+ void *nativeImageHandle;
+ QString nativeImageType;
+#endif
+
+ void forceToImage(bool allowReadback = true);
QImage::Format sourceFormat() const;
+ QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const;
+ void updateSerial();
void destroyImageAndContext();
void destroyImages();
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index 2ea38c1..0d2ed9e 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -41,10 +41,10 @@
#include "qpixmapdata_vg_p.h"
#include "qvgfontglyphcache_p.h"
+#include <QtGui/private/qnativeimagehandleprovider_p.h>
#include <private/qt_s60_p.h>
#include <fbs.h>
-#include <bitdev.h>
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
# include <sgresource/sgimage.h>
@@ -75,33 +75,6 @@ VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
extern int qt_vg_pixmap_serial;
-static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
-{
- CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
- if(!copy)
- return 0;
-
- if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
- delete copy;
- copy = 0;
-
- return 0;
- }
-
- CFbsBitmapDevice* bitmapDevice = 0;
- CFbsBitGc *bitmapGc = 0;
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- bitmapGc->BitBlt(TPoint(), bitmap);
-
- delete bitmapGc;
- delete bitmapDevice;
-
- return copy;
-}
-
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
{
@@ -136,7 +109,59 @@ void QVGPixmapData::cleanup()
{
is_null = w = h = 0;
recreate = false;
- source = QImage();
+ source = QVolatileImage();
+}
+
+bool QVGPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
+{
+ if (type == QLatin1String("RSgImage")) {
+ fromNativeType(handle, QPixmapData::SgImage);
+ return true;
+ } else if (type == QLatin1String("CFbsBitmap")) {
+ fromNativeType(handle, QPixmapData::FbsBitmap);
+ return true;
+ }
+ return false;
+}
+
+void QVGPixmapData::createFromNativeImageHandleProvider()
+{
+ void *handle = 0;
+ QString type;
+ nativeImageHandleProvider->get(&handle, &type);
+ if (handle) {
+ if (initFromNativeImageHandle(handle, type)) {
+ nativeImageHandle = handle;
+ nativeImageType = type;
+ } else {
+ qWarning("QVGPixmapData: Unknown native image type '%s'", qPrintable(type));
+ }
+ } else {
+ qWarning("QVGPixmapData: Native handle is null");
+ }
+}
+
+void QVGPixmapData::releaseNativeImageHandle()
+{
+ if (nativeImageHandleProvider && nativeImageHandle) {
+ nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
+ nativeImageHandle = 0;
+ nativeImageType = QString();
+ }
+}
+
+static inline bool conversionLessFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16: // EColor64K
+ case QImage::Format_RGB32: // EColor16MU
+ case QImage::Format_ARGB32: // EColor16MA
+ case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
+ case QImage::Format_Indexed8: // EGray256, EColor256
+ return true;
+ default:
+ return false;
+ }
}
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
@@ -155,55 +180,37 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
}
is_null = (w <= 0 || h <= 0);
- source = QImage(); // vgGetImageSubData() some day?
+ source = QVolatileImage(); // readback will be done later, only when needed
recreate = false;
prevSize = QSize(w, h);
- //setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
-
- bool deleteSourceBitmap = false;
-#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
-
- // Rasterize extended bitmaps
-
- TUid extendedBitmapType = bitmap->ExtendedBitmapType();
- if (extendedBitmapType != KNullUid) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
+ } else if (type == QPixmapData::FbsBitmap && pixmap) {
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
+ QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
+ resize(size.width(), size.height());
+ source = QVolatileImage(bitmap); // duplicates only, if possible
+ if (source.isNull())
+ return;
+ if (!conversionLessFormat(source.format())) {
+ // Here we may need to copy if the formats do not match.
+ // (e.g. for display modes other than EColor16MAP and EColor16MU)
+ source.beginDataAccess();
+ QImage::Format format = idealFormat(&source.imageRef(), Qt::AutoColor);
+ source.endDataAccess(true);
+ source.ensureFormat(format);
}
-#endif
-
- if (bitmap->IsCompressedInRAM()) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
- }
-
- TDisplayMode displayMode = bitmap->DisplayMode();
- QImage::Format format = qt_TDisplayMode2Format(displayMode);
-
- TSize size = bitmap->SizeInPixels();
- int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode);
-
- bitmap->BeginDataAccess();
- uchar *bytes = (uchar*)bitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
- img = img.copy();
- bitmap->EndDataAccess();
-
- if(displayMode == EGray2) {
- //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
- //So invert mono bitmaps so that masks work correctly.
- img.invertPixels();
- } else if(displayMode == EColor16M) {
- img = img.rgbSwapped(); // EColor16M is BGR
- }
-
- fromImage(img, Qt::AutoColor);
-
- if(deleteSourceBitmap)
- delete bitmap;
+ recreate = true;
+ } else if (type == QPixmapData::VolatileImage && pixmap) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
+ resize(img->width(), img->height());
+ source = *img;
+ recreate = true;
+ } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
+ destroyImages();
+ nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
+ // Cannot defer the retrieval, we need at least the size right away.
+ createFromNativeImageHandleProvider();
}
}
@@ -270,26 +277,13 @@ void* QVGPixmapData::toNativeType(NativeType type)
driver.Close();
return reinterpret_cast<void*>(sgImage.take());
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
-
- if (bitmap) {
- if (bitmap->Create(TSize(source.width(), source.height()),
- EColor16MAP) == KErrNone) {
- const uchar *sptr = const_cast<const QImage&>(source).bits();
- bitmap->BeginDataAccess();
-
- uchar *dptr = (uchar*)bitmap->DataAddress();
- Mem::Copy(dptr, sptr, source.byteCount());
-
- bitmap->EndDataAccess();
- } else {
- delete bitmap;
- bitmap = 0;
- }
+ } else if (type == QPixmapData::FbsBitmap && isValid()) {
+ ensureReadback(true);
+ if (source.isNull()) {
+ source = QVolatileImage(w, h, sourceFormat());
}
-
- return reinterpret_cast<void*>(bitmap);
+ // Just duplicate the bitmap handle, no data copying happens.
+ return source.duplicateNativeImage();
}
return 0;
}
diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h
index 9a105ec..ce12301 100644
--- a/src/openvg/qvgfontglyphcache_p.h
+++ b/src/openvg/qvgfontglyphcache_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qfontengine_p.h>
-#include <qvg_p.h>
+#include "qvg_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp
index a2b1c4e..7a7ec78 100644
--- a/src/openvg/qvgimagepool.cpp
+++ b/src/openvg/qvgimagepool.cpp
@@ -175,8 +175,19 @@ bool QVGImagePool::reclaimSpace(VGImageFormat format,
void QVGImagePool::hibernate()
{
- // Nothing to do here at the moment since the pool does not
- // retain VGImage's after they have been released.
+ Q_D(QVGImagePool);
+ QVGPixmapData *pd = d->lruLast;
+ while (pd) {
+ QVGPixmapData *prevLRU = pd->prevLRU;
+ pd->inImagePool = false;
+ pd->inLRU = false;
+ pd->nextLRU = 0;
+ pd->prevLRU = 0;
+ pd->hibernate();
+ pd = prevLRU;
+ }
+ d->lruFirst = 0;
+ d->lruLast = 0;
}
void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp
index ca80886..866453f 100644
--- a/src/openvg/qwindowsurface_vgegl.cpp
+++ b/src/openvg/qwindowsurface_vgegl.cpp
@@ -768,6 +768,11 @@ bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int
context->lazyDoneCurrent();
return true;
}
+#else
+ Q_UNUSED(widget);
+ Q_UNUSED(area);
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
#endif
return false;
}
diff --git a/src/plugins/audio/audio.pro b/src/plugins/audio/audio.pro
deleted file mode 100644
index b7a775b..0000000
--- a/src/plugins/audio/audio.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS =
-
diff --git a/src/plugins/bearer/icd/dbusdispatcher.cpp b/src/plugins/bearer/icd/dbusdispatcher.cpp
index 13cd8a9..a317cb4 100644
--- a/src/plugins/bearer/icd/dbusdispatcher.cpp
+++ b/src/plugins/bearer/icd/dbusdispatcher.cpp
@@ -194,18 +194,21 @@ static bool appendVariantToDBusMessage(const QVariant& argument,
&int32_data);
break;
- case QVariant::String:
- str_data = argument.toString().toLatin1().data();
+ case QVariant::String: {
+ QByteArray data = argument.toString().toLatin1();
+ str_data = data.data();
dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_STRING,
&str_data);
break;
+ }
case QVariant::StringList:
str_list = argument.toStringList();
dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
"s", &array_iter);
for (idx = 0; idx < str_list.size(); idx++) {
- str_data = str_list.at(idx).toLatin1().data();
+ QByteArray data = str_list.at(idx).toLatin1();
+ str_data = data.data();
dbus_message_iter_append_basic(&array_iter,
DBUS_TYPE_STRING,
&str_data);
diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp
index af5d85e..94a6c81 100644
--- a/src/plugins/bearer/icd/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp
@@ -621,21 +621,21 @@ static QString get_network_interface()
if (ret == 0) {
/* No results */
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "Cannot get addrinfo from icd, are you connected or is icd running?";
+ qDebug() << "Cannot get addrinfo from icd, are you connected or is icd running?";
#endif
- return iface;
+ return iface;
}
if (addr_results.first().ip_info.isEmpty())
- return QString();
+ return QString();
- const char *address = addr_results.first().ip_info.first().address.toAscii().constData();
+ QByteArray data = addr_results.first().ip_info.first().address.toAscii();
struct in_addr addr;
- if (inet_aton(address, &addr) == 0) {
+ if (inet_aton(data.constData(), &addr) == 0) {
#ifdef BEARER_MANAGEMENT_DEBUG
- qDebug() << "address" << address << "invalid";
+ qDebug() << "address" << data.constData() << "invalid";
#endif
- return iface;
+ return iface;
}
struct ifaddrs *ifaddr, *ifa;
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index 30d6b50..6b37b38 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -213,6 +213,11 @@ void QNetworkManagerEngine::connectToId(const QString &id)
dbusDevicePath = devicePath.path();
break;
}
+ else if (device.deviceType() == DEVICE_TYPE_GSM &&
+ connectionType == QLatin1String("gsm")) {
+ dbusDevicePath = devicePath.path();
+ break;
+ }
}
const QString service = connection->connectionInterface()->service();
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index fc480c2..f367c26 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -150,16 +150,15 @@ SymbianEngine::~SymbianEngine()
iConnectionMonitor.CancelNotifications();
iConnectionMonitor.Close();
-
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- iCmManager.Close();
-#endif
-
- // CCommsDatabase destructor uses cleanup stack. Since QNetworkConfigurationManager
+
+ // CCommsDatabase destructor and RCmManager.Close() use cleanup stack. Since QNetworkConfigurationManager
// is a global static, but the time we are here, E32Main() has been exited already and
// the thread's default cleanup stack has been deleted. Without this line, a
// 'E32USER-CBase 69' -panic will occur.
CTrapCleanup* cleanup = CTrapCleanup::New();
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ iCmManager.Close();
+#endif
delete ipCommsDB;
delete cleanup;
}
@@ -829,6 +828,7 @@ void SymbianEngine::updateStatesToSnaps()
discovered = true;
}
}
+ snapConfigLocker.unlock();
if (active) {
changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
} else if (discovered) {
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index dc74c4e..6d6fb02 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -1025,11 +1025,10 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m
case QPainter::CompositionMode_DestinationOut:
surface->SetPorterDuff(surface, DSPD_DST_OUT);
break;
-#if (Q_DIRECTFB_VERSION >= 0x010209)
case QPainter::CompositionMode_Destination:
- surface->SetPorterDuff(surface, DSPD_DST);
+ surface->SetSrcBlendFunction(surface, DSBF_ZERO);
+ surface->SetDstBlendFunction(surface, DSBF_ONE);
break;
-#endif
#if (Q_DIRECTFB_VERSION >= 0x010000)
case QPainter::CompositionMode_SourceAtop:
surface->SetPorterDuff(surface, DSPD_SRC_ATOP);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index 3d8cf50..9a94c30 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -365,10 +365,12 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
if (!win)
return;
-#ifndef QT_NO_QWS_PROXYSCREEN
+#if !defined(QT_NO_QWS_PROXYSCREEN) && !defined(QT_NO_GRAPHICSVIEW)
QWExtra *extra = qt_widget_private(widget)->extraData();
if (extra && extra->proxyWidget)
return;
+#else
+ Q_UNUSED(widget);
#endif
const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
index a70d232..69a6922 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
@@ -59,10 +59,16 @@
#include "qmeegographicssystem.h"
#include "qmeegoextensions.h"
+#include <QTimer>
+
bool QMeeGoGraphicsSystem::surfaceWasCreated = false;
QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps;
+QList<QMeeGoSwitchCallback> QMeeGoGraphicsSystem::switchCallbacks;
+
+QMeeGoGraphicsSystem::SwitchPolicy QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::AutomaticSwitch;
+
QMeeGoGraphicsSystem::QMeeGoGraphicsSystem()
{
qDebug("Using the meego graphics system");
@@ -74,6 +80,115 @@ QMeeGoGraphicsSystem::~QMeeGoGraphicsSystem()
qt_destroy_gl_share_widget();
}
+class QMeeGoGraphicsSystemSwitchHandler : public QObject
+{
+ Q_OBJECT
+public:
+ QMeeGoGraphicsSystemSwitchHandler();
+
+ void addWidget(QWidget *widget);
+ bool eventFilter(QObject *, QEvent *);
+
+ void handleMapNotify();
+
+private slots:
+ void removeWidget(QObject *object);
+ void switchToRaster();
+ void switchToMeeGo();
+
+private:
+ int visibleWidgets() const;
+
+private:
+ QList<QWidget *> m_widgets;
+};
+
+typedef bool(*QX11FilterFunction)(XEvent *event);
+Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func);
+
+static bool x11EventFilter(XEvent *event);
+
+QMeeGoGraphicsSystemSwitchHandler::QMeeGoGraphicsSystemSwitchHandler()
+{
+ qt_installX11EventFilter(x11EventFilter);
+}
+
+void QMeeGoGraphicsSystemSwitchHandler::addWidget(QWidget *widget)
+{
+ if (widget != qt_gl_share_widget() && !m_widgets.contains(widget)) {
+ widget->installEventFilter(this);
+ connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(removeWidget(QObject *)));
+ m_widgets << widget;
+ }
+}
+
+void QMeeGoGraphicsSystemSwitchHandler::handleMapNotify()
+{
+ if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
+ QTimer::singleShot(0, this, SLOT(switchToMeeGo()));
+}
+
+void QMeeGoGraphicsSystemSwitchHandler::removeWidget(QObject *object)
+{
+ m_widgets.removeOne(static_cast<QWidget *>(object));
+ if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
+ QTimer::singleShot(0, this, SLOT(switchToRaster()));
+}
+
+void QMeeGoGraphicsSystemSwitchHandler::switchToRaster()
+{
+ QMeeGoGraphicsSystem::switchToRaster();
+}
+
+void QMeeGoGraphicsSystemSwitchHandler::switchToMeeGo()
+{
+ QMeeGoGraphicsSystem::switchToMeeGo();
+}
+
+int QMeeGoGraphicsSystemSwitchHandler::visibleWidgets() const
+{
+ int count = 0;
+ for (int i = 0; i < m_widgets.size(); ++i)
+ count += m_widgets.at(i)->isVisible() && !(m_widgets.at(i)->windowState() & Qt::WindowMinimized);
+ return count;
+}
+
+bool QMeeGoGraphicsSystemSwitchHandler::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::WindowStateChange
+ && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
+ {
+ QWindowStateChangeEvent *change = static_cast<QWindowStateChangeEvent *>(event);
+ QWidget *widget = static_cast<QWidget *>(object);
+
+ Qt::WindowStates current = widget->windowState();
+ Qt::WindowStates old = change->oldState();
+
+ // did minimized flag change?
+ if ((current ^ old) & Qt::WindowMinimized) {
+ if (current & Qt::WindowMinimized) {
+ if (visibleWidgets() == 0)
+ QMeeGoGraphicsSystem::switchToRaster();
+ } else {
+ if (visibleWidgets() > 0)
+ QMeeGoGraphicsSystem::switchToMeeGo();
+ }
+ }
+ }
+
+ // resume processing of event
+ return false;
+}
+
+Q_GLOBAL_STATIC(QMeeGoGraphicsSystemSwitchHandler, switch_handler)
+
+bool x11EventFilter(XEvent *event)
+{
+ if (event->type == MapNotify)
+ switch_handler()->handleMapNotify();
+ return false;
+}
+
QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const
{
QGLWidget *shareWidget = qt_gl_share_widget();
@@ -83,6 +198,9 @@ QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const
QGLShareContextScope ctx(shareWidget->context());
+ if (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime"))
+ switch_handler()->addWidget(widget);
+
QMeeGoGraphicsSystem::surfaceWasCreated = true;
QWindowSurface *surface = new QGLWindowSurface(widget);
return surface;
@@ -171,7 +289,7 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl
return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
} else {
QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
- pmd->fromImage(softImage, Qt::NoOpaqueDetection);
+ pmd->fromImage(softImage, Qt::NoFormatConversion);
// Make sure that the image was not converted in any way
if (pmd->buffer()->data_ptr()->data !=
@@ -203,18 +321,7 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
bool QMeeGoGraphicsSystem::meeGoRunning()
{
- if (! QApplicationPrivate::instance()) {
- qWarning("Application not running just yet... hard to know what system running!");
- return false;
- }
-
- QString name = QApplicationPrivate::instance()->graphics_system_name;
- if (name == "runtime") {
- QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
- name = rsystem->graphicsSystemName();
- }
-
- return (name == "meego");
+ return runningGraphicsSystemName() == "meego";
}
QPixmapData* QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
@@ -259,6 +366,69 @@ void QMeeGoGraphicsSystem::destroyFenceSync(void *fenceSync)
QMeeGoExtensions::eglDestroySyncKHR(QEgl::display(), fenceSync);
}
+QString QMeeGoGraphicsSystem::runningGraphicsSystemName()
+{
+ if (!QApplicationPrivate::instance()) {
+ qWarning("Querying graphics system but application not running yet!");
+ return QString();
+ }
+
+ QString name = QApplicationPrivate::instance()->graphics_system_name;
+ if (name == QLatin1String("runtime")) {
+ QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
+ name = rsystem->graphicsSystemName();
+ }
+
+ return name;
+}
+
+void QMeeGoGraphicsSystem::switchToMeeGo()
+{
+ if (switchPolicy == NoSwitch || meeGoRunning())
+ return;
+
+ if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
+ qWarning("Can't switch to meego - switching only supported with 'runtime' graphics system.");
+ else {
+ triggerSwitchCallbacks(0, "meego");
+
+ QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
+ app->setGraphicsSystem(QLatin1String("meego"));
+
+ triggerSwitchCallbacks(1, "meego");
+ }
+}
+
+void QMeeGoGraphicsSystem::switchToRaster()
+{
+ if (switchPolicy == NoSwitch || runningGraphicsSystemName() == QLatin1String("raster"))
+ return;
+
+ if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
+ qWarning("Can't switch to raster - switching only supported with 'runtime' graphics system.");
+ else {
+ triggerSwitchCallbacks(0, "raster");
+
+ QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
+ app->setGraphicsSystem(QLatin1String("raster"));
+
+ QMeeGoLivePixmapData::invalidateSurfaces();
+
+ triggerSwitchCallbacks(1, "raster");
+ }
+}
+
+void QMeeGoGraphicsSystem::registerSwitchCallback(QMeeGoSwitchCallback callback)
+{
+ switchCallbacks << callback;
+}
+
+void QMeeGoGraphicsSystem::triggerSwitchCallbacks(int type, const char *name)
+{
+ for (int i = 0; i < switchCallbacks.size(); ++i)
+ switchCallbacks.at(i)(type, name);
+}
+
/* C API */
int qt_meego_image_to_egl_shared_image(const QImage &image)
@@ -335,3 +505,30 @@ void qt_meego_destroy_fence_sync(void* fs)
{
return QMeeGoGraphicsSystem::destroyFenceSync(fs);
}
+
+void qt_meego_invalidate_live_surfaces(void)
+{
+ return QMeeGoLivePixmapData::invalidateSurfaces();
+}
+
+void qt_meego_switch_to_raster(void)
+{
+ QMeeGoGraphicsSystem::switchToRaster();
+}
+
+void qt_meego_switch_to_meego(void)
+{
+ QMeeGoGraphicsSystem::switchToMeeGo();
+}
+
+void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback)
+{
+ QMeeGoGraphicsSystem::registerSwitchCallback(callback);
+}
+
+void qt_meego_set_switch_policy(int policy)
+{
+ QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::SwitchPolicy(policy);
+}
+
+#include "qmeegographicssystem.moc"
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
index 323ce1f..3528425 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
@@ -47,9 +47,13 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+extern "C" typedef void (*QMeeGoSwitchCallback)(int type, const char *name);
+
class QMeeGoGraphicsSystem : public QGraphicsSystem
{
public:
+ enum SwitchPolicy { AutomaticSwitch, ManualSwitch, NoSwitch };
+
QMeeGoGraphicsSystem();
~QMeeGoGraphicsSystem();
@@ -76,13 +80,23 @@ public:
static void* createFenceSync();
static void destroyFenceSync(void* fenceSync);
+ static void switchToRaster();
+ static void switchToMeeGo();
+ static QString runningGraphicsSystemName();
+
+ static void registerSwitchCallback(QMeeGoSwitchCallback callback);
+
+ static SwitchPolicy switchPolicy;
+
private:
static bool meeGoRunning();
static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap);
static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd);
+ static void triggerSwitchCallbacks(int type, const char *name);
static bool surfaceWasCreated;
- static QHash <Qt::HANDLE, QPixmap*> liveTexturePixmaps;
+ static QHash<Qt::HANDLE, QPixmap*> liveTexturePixmaps;
+ static QList<QMeeGoSwitchCallback> switchCallbacks;
};
/* C api */
@@ -95,7 +109,7 @@ extern "C" {
Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle);
Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height);
Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height);
- Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
+ Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle);
Q_DECL_EXPORT QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync);
@@ -103,6 +117,11 @@ extern "C" {
Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
Q_DECL_EXPORT void* qt_meego_create_fence_sync(void);
Q_DECL_EXPORT void qt_meego_destroy_fence_sync(void* fs);
+ Q_DECL_EXPORT void qt_meego_invalidate_live_surfaces(void);
+ Q_DECL_EXPORT void qt_meego_switch_to_raster(void);
+ Q_DECL_EXPORT void qt_meego_switch_to_meego(void);
+ Q_DECL_EXPORT void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback);
+ Q_DECL_EXPORT void qt_meego_set_switch_policy(int policy);
}
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
index e4f1900..b6ba7ec 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
@@ -49,6 +49,8 @@
#include <private/qpixmap_x11_p.h>
#include <stdio.h>
+static QMeeGoLivePixmapDataList all_live_pixmaps;
+
static EGLint lock_attribs[] = {
EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
@@ -118,21 +120,29 @@ QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format)
backingX11Pixmap = new QPixmap(pmd);
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
{
backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
{
delete backingX11Pixmap;
+ all_live_pixmaps.erase(pos);
}
void QMeeGoLivePixmapData::initializeThroughEGLImage()
{
+ if (texture()->id != 0)
+ return;
+
QGLShareContextScope ctx(qt_gl_share_widget()->context());
QMeeGoExtensions::ensureInitialized();
@@ -184,6 +194,8 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
void *data = 0;
int pitch = 0;
+ int surfaceWidth = 0;
+ int surfaceHeight = 0;
EGLSurface surface = 0;
QImage::Format format;
lockedImage = QImage();
@@ -196,9 +208,11 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data);
eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch);
+ eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth);
+ eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight);
// Ok, here we know we just support those two formats. Real solution would be:
- // uqery also the format.
+ // query also the format.
if (backingX11Pixmap->depth() > 16)
format = QImage::Format_ARGB32_Premultiplied;
else
@@ -209,7 +223,13 @@ QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
return &lockedImage;
}
- lockedImage = QImage((uchar *) data, width(), height(), format);
+ if (width() != surfaceWidth || height() != surfaceHeight) {
+ qWarning("Live texture dimensions don't match!");
+ QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface);
+ return &lockedImage;
+ }
+
+ lockedImage = QImage((uchar *) data, width(), height(), pitch, format);
return &lockedImage;
}
@@ -245,6 +265,8 @@ bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
{
+ initializeThroughEGLImage();
+
// This code is a crative remix of the stuff that can be found in the
// Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(backingX11Pixmap->data_ptr().data());
@@ -290,3 +312,12 @@ void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
pixmapData->gl_surface = 0;
}
}
+
+void QMeeGoLivePixmapData::invalidateSurfaces()
+{
+ foreach (QMeeGoLivePixmapData *data, all_live_pixmaps) {
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(data->backingX11Pixmap->data_ptr().data());
+ *data->texture() = QGLTexture();
+ pixmapData->gl_surface = 0;
+ }
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
index 484028e..616b33c 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
@@ -42,9 +42,13 @@
#ifndef MLIVEPIXMAPDATA_H
#define MLIVEPIXMAPDATA_H
+#include <QLinkedList>
#include <private/qpixmapdata_gl_p.h>
#include "qmeegoextensions.h"
+class QMeeGoLivePixmapData;
+typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList;
+
class QMeeGoLivePixmapData : public QGLPixmapData
{
public:
@@ -66,6 +70,9 @@ public:
QPixmap *backingX11Pixmap;
QImage lockedImage;
+ QMeeGoLivePixmapDataList::Iterator pos;
+
+ static void invalidateSurfaces();
};
#endif
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
index 0c107b5..4b4f677 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
@@ -42,7 +42,8 @@
#include "qgraphicssystem_vg_p.h"
#include <QtOpenVG/private/qpixmapdata_vg_p.h>
#include <QtOpenVG/private/qwindowsurface_vg_p.h>
-#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
+#include <QtOpenVG/private/qvgimagepool_p.h>
+#if defined(Q_OS_SYMBIAN)
#include <QtGui/private/qwidget_p.h>
#endif
#include <QtGui/private/qapplication_p.h>
@@ -69,12 +70,19 @@ QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) co
QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
{
-#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
- QWidgetPrivate *d = qt_widget_private(widget);
- if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
- return d->createDefaultWindowSurface_sys();
+#if defined(Q_OS_SYMBIAN)
+ if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
+ QWidgetPrivate *d = qt_widget_private(widget);
+ if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
+ return d->createDefaultWindowSurface_sys();
+ }
#endif
return new QVGWindowSurface(widget);
}
+void QVGGraphicsSystem::releaseCachedResources()
+{
+ QVGImagePool::instance()->hibernate();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
index d1bce28..9c9b3e2 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
@@ -64,6 +64,8 @@ public:
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
+
+ void releaseCachedResources();
};
QT_END_NAMESPACE
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index afa0901..e778ab7 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -13,5 +13,4 @@ embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers
!symbian:!contains(QT_CONFIG, no-gui):SUBDIRS += accessible
symbian:SUBDIRS += s60
contains(QT_CONFIG, phonon): SUBDIRS *= phonon
-contains(QT_CONFIG, multimedia): SUBDIRS *= audio
contains(QT_CONFIG, declarative): SUBDIRS *= qmltooling
diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri
index 7cbffe0..6c33e92 100644
--- a/src/plugins/qpluginbase.pri
+++ b/src/plugins/qpluginbase.pri
@@ -1,6 +1,6 @@
TEMPLATE = lib
isEmpty(QT_MAJOR_VERSION) {
- VERSION=4.7.2
+ VERSION=4.7.4
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pri b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pri
index 494c64c..b7a87f3 100644
--- a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pri
+++ b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pri
@@ -1,6 +1,12 @@
# We just want to include the sqlite3 binaries for Symbian for platforms that do not have them.
!symbian-abld:!symbian-sbsv2 {
!symbian_no_export_sqlite:!exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) {
+ contains(QMAKE_HOST.os,Windows) {
+ # Trick on Windows to do a touch on the file, since copy keeps the timestamp.
+ copyWithTouch = copy /y /b NUL+
+ } else {
+ copyWithTouch = "$$QMAKE_COPY "
+ }
symbian_sqlite3_zip_file = $$PWD/SQLite3_v9.2.zip
# The QMAKE_COPY section is to update timestamp on the file.
@@ -10,7 +16,7 @@
symbian_sqlite3_header.CONFIG = combine no_link
symbian_sqlite3_header.dependency_type = TYPE_C
symbian_sqlite3_header.commands = $$QMAKE_UNZIP -j ${QMAKE_FILE_NAME} epoc32/include/stdapis/${QMAKE_FILE_OUT_BASE}.h \
- && $$QMAKE_COPY ${QMAKE_FILE_OUT_BASE}.h ${QMAKE_FILE_OUT}.tmp \
+ && $${copyWithTouch}${QMAKE_FILE_OUT_BASE}.h ${QMAKE_FILE_OUT}.tmp \
&& $$QMAKE_DEL_FILE ${QMAKE_FILE_OUT_BASE}.h \
&& $$QMAKE_MOVE ${QMAKE_FILE_OUT}.tmp ${QMAKE_FILE_OUT}
silent:symbian_sqlite3_header.commands = @echo unzipping $@ && $$symbian_sqlite3_header.commands
@@ -22,12 +28,18 @@
!isEmpty(OBJECTS_DIR):symbian_sqlite3_dso.output = $$OBJECTS_DIR/$$symbian_sqlite3_dso.output
symbian_sqlite3_dso.CONFIG = combine no_link target_predeps
symbian_sqlite3_dso.commands = $$QMAKE_UNZIP -j ${QMAKE_FILE_NAME} epoc32/release/armv5/lib/${QMAKE_FILE_OUT_BASE}.dso \
- && $$QMAKE_COPY ${QMAKE_FILE_OUT_BASE}.dso ${QMAKE_FILE_OUT}.tmp \
+ && $${copyWithTouch}${QMAKE_FILE_OUT_BASE}.dso ${QMAKE_FILE_OUT}.tmp \
&& $$QMAKE_DEL_FILE ${QMAKE_FILE_OUT_BASE}.dso \
&& $$QMAKE_MOVE ${QMAKE_FILE_OUT}.tmp ${QMAKE_FILE_OUT}
silent:symbian_sqlite3_dso.commands = @echo unzipping $@ && $$symbian_sqlite3_dso.commands
QMAKE_EXTRA_COMPILERS += symbian_sqlite3_dso
+ # Workaround for the fact that make doesn't understand that sqlite3.dso
+ # is the same as $OBJECTS_DIR/sqlite3.dso
+ symbian_sqlite3_dso_standalone.target = sqlite3.dso
+ symbian_sqlite3_dso_standalone.depends = $$symbian_sqlite3_dso.output
+ QMAKE_EXTRA_TARGETS += symbian_sqlite3_dso_standalone
+
symbian_sqlite3_ver_dso.input = symbian_sqlite3_zip_file
symbian_sqlite3_ver_dso.output = sqlite3{00060003}.dso
!isEmpty(OBJECTS_DIR):symbian_sqlite3_ver_dso.output = $$OBJECTS_DIR/$$symbian_sqlite3_ver_dso.output
diff --git a/src/qbase.pri b/src/qbase.pri
index 75da3dc..5d78336 100644
--- a/src/qbase.pri
+++ b/src/qbase.pri
@@ -4,7 +4,7 @@ INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat
isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700
TEMPLATE = lib
isEmpty(QT_MAJOR_VERSION) {
- VERSION=4.7.2
+ VERSION=4.7.4
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/qt3support/tools/q3asciidict.qdoc b/src/qt3support/tools/q3asciidict.qdoc
index e744633..c276682 100644
--- a/src/qt3support/tools/q3asciidict.qdoc
+++ b/src/qt3support/tools/q3asciidict.qdoc
@@ -43,7 +43,7 @@
performace as a Q3AsciiDict.
Example:
- \snippet doc/src/snippets/code/doc_src_q3asciidict.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3asciidict.cpp 0
In this example we use a dictionary to keep track of the line
edits we're using. We insert each line edit into the dictionary
with a unique name and then access the line edits via the
@@ -164,7 +164,7 @@
\a item may not be 0.
Equivalent to:
- \snippet doc/src/snippets/code/doc_src_q3asciidict.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3asciidict.cpp 1
If there are two or more items with equal keys, then the most
recently inserted item will be replaced.
@@ -295,7 +295,7 @@
iterator that operates on Q3AsciiDict\<X\> (dictionary of X*).
Example:
- \snippet doc/src/snippets/code/doc_src_q3asciidict.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3asciidict.cpp 2
In the example we insert some line edits into a dictionary, then
iterate over the dictionary printing the strings associated with
those line edits.
diff --git a/src/qt3support/tools/q3dict.qdoc b/src/qt3support/tools/q3dict.qdoc
index 6b221f1..8fcbba4 100644
--- a/src/qt3support/tools/q3dict.qdoc
+++ b/src/qt3support/tools/q3dict.qdoc
@@ -192,7 +192,7 @@
\a item may not be 0.
Equivalent to:
- \snippet doc/src/snippets/code/doc_src_q3dict.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3dict.cpp 0
If there are two or more items with equal keys, then the last item
that was inserted will be replaced.
@@ -326,7 +326,7 @@
point to the next item in the (arbitrary) traversal order.
Example:
- \snippet doc/src/snippets/code/doc_src_q3dict.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3dict.cpp 1
In the example we insert some pointers to line edits into a
dictionary, then iterate over the dictionary printing the strings
associated with the line edits.
diff --git a/src/qt3support/tools/q3intdict.qdoc b/src/qt3support/tools/q3intdict.qdoc
index 684fc63..f108f30 100644
--- a/src/qt3support/tools/q3intdict.qdoc
+++ b/src/qt3support/tools/q3intdict.qdoc
@@ -39,7 +39,7 @@
pointer. Dictionaries provide very fast insertion and lookup.
Example:
- \snippet doc/src/snippets/code/doc_src_q3intdict.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3intdict.cpp 0
See Q3Dict for full details, including the choice of dictionary
size, and how deletions are handled.
@@ -145,7 +145,7 @@
\a item may not be 0.
Equivalent to:
- \snippet doc/src/snippets/code/doc_src_q3intdict.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3intdict.cpp 1
If there are two or more items with equal keys, then the most
recently inserted item will be replaced.
@@ -270,7 +270,7 @@
iterator that operates on Q3IntDict\<X\> (dictionary of X*).
Example:
- \snippet doc/src/snippets/code/doc_src_q3intdict.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3intdict.cpp 2
Note that the traversal order is arbitrary; you are not guaranteed the
order shown above.
diff --git a/src/qt3support/tools/q3memarray.qdoc b/src/qt3support/tools/q3memarray.qdoc
index f05f433..5d6f9b2 100644
--- a/src/qt3support/tools/q3memarray.qdoc
+++ b/src/qt3support/tools/q3memarray.qdoc
@@ -51,7 +51,7 @@
and less copying of data.
Example:
- \snippet doc/src/snippets/code/doc_src_q3memarray.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3memarray.cpp 0
Program output:
\snippet doc/src/snippets/code/doc_src_q3memarray.qdoc 1
@@ -63,7 +63,7 @@
the remaining bytes will typically be uninitialized, this can
cause find() etc. to fail to find the element. Example:
- \snippet doc/src/snippets/code/doc_src_q3memarray.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3memarray.cpp 2
To work around this, make sure that you use a struct where
sizeof() returns the same as the sum of the sizes of the members
@@ -352,10 +352,10 @@
allocating memory or copying data.
Example I (intended use):
- \snippet doc/src/snippets/code/doc_src_q3memarray.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_q3memarray.cpp 3
Example II (you don't want to do this):
- \snippet doc/src/snippets/code/doc_src_q3memarray.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_q3memarray.cpp 4
\warning If you do not call resetRawData(), Q3MemArray will attempt
to deallocate or reallocate the raw data, which might not be too
diff --git a/src/qt3support/tools/q3ptrdict.qdoc b/src/qt3support/tools/q3ptrdict.qdoc
index 8831a55..21dcdfd 100644
--- a/src/qt3support/tools/q3ptrdict.qdoc
+++ b/src/qt3support/tools/q3ptrdict.qdoc
@@ -39,7 +39,7 @@
pointer. Dictionaries provide very fast insertion and lookup.
Example:
- \snippet doc/src/snippets/code/doc_src_q3ptrdict.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3ptrdict.cpp 0
In this example we use a dictionary to add an extra property (a
char*) to the line edits we're using.
@@ -147,7 +147,7 @@
\a item may not be 0.
Equivalent to
- \snippet doc/src/snippets/code/doc_src_q3ptrdict.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3ptrdict.cpp 1
If there are two or more items with equal keys, then the most
recently inserted item will be replaced.
@@ -272,7 +272,7 @@
iterator that operates on Q3PtrDict\<X\> (dictionary of X*).
Example:
- \snippet doc/src/snippets/code/doc_src_q3ptrdict.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3ptrdict.cpp 2
In the example we insert some line edits into a dictionary,
associating a string with each. We then iterate over the
dictionary printing the associated strings.
diff --git a/src/qt3support/tools/q3ptrlist.qdoc b/src/qt3support/tools/q3ptrlist.qdoc
index 13e478e..e19d6bf 100644
--- a/src/qt3support/tools/q3ptrlist.qdoc
+++ b/src/qt3support/tools/q3ptrlist.qdoc
@@ -54,10 +54,10 @@
\target example
Example:
- \snippet doc/src/snippets/code/doc_src_q3ptrlist.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3ptrlist.cpp 0
The output is
- \snippet doc/src/snippets/code/doc_src_q3ptrlist.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3ptrlist.cpp 1
Q3PtrList has several member functions for traversing the list, but
using a Q3PtrListIterator can be more practical. Multiple list
@@ -353,7 +353,7 @@
auto-deletion\endlink is enabled.
Equivalent to:
- \snippet doc/src/snippets/code/doc_src_q3ptrlist.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3ptrlist.cpp 2
The item after the removed item becomes the new current list item
if the removed item is not the last item in the list. If the last
@@ -785,10 +785,10 @@
but it uses Q3PtrListIterator. The class Employee is
defined there.
- \snippet doc/src/snippets/code/doc_src_q3ptrlist.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_q3ptrlist.cpp 3
The output is
- \snippet doc/src/snippets/code/doc_src_q3ptrlist.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_q3ptrlist.cpp 4
Using a list iterator is a more robust way of traversing the list
than using the Q3PtrList member functions \link Q3PtrList::first()
diff --git a/src/qt3support/tools/q3valuelist.qdoc b/src/qt3support/tools/q3valuelist.qdoc
index 99f1634..a5ebf60 100644
--- a/src/qt3support/tools/q3valuelist.qdoc
+++ b/src/qt3support/tools/q3valuelist.qdoc
@@ -71,7 +71,7 @@
prefer to use the STL-compatible functions.
Example:
- \snippet doc/src/snippets/code/doc_src_q3valuelist.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3valuelist.cpp 0
Notice that the latest changes to Mary's salary did not affect the
@@ -99,7 +99,7 @@
(your application will crash or do unpredictable things). Use
last() and first() with caution, for example:
- \snippet doc/src/snippets/code/doc_src_q3valuelist.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3valuelist.cpp 1
Because Q3ValueList is value-based there is no need to be careful
about deleting items in the list. The list holds its own copies
@@ -352,7 +352,7 @@
Use the end() function instead. For example:
- \snippet doc/src/snippets/code/doc_src_q3valuelist.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3valuelist.cpp 2
*/
@@ -364,7 +364,7 @@
Use the end() function instead. For example:
- \snippet doc/src/snippets/code/doc_src_q3valuelist.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_q3valuelist.cpp 3
*/
@@ -443,7 +443,7 @@
iterator.
Example (see Q3ValueList for the complete code):
- \snippet doc/src/snippets/code/doc_src_q3valuelist.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_q3valuelist.cpp 4
Q3ValueList is highly optimized for performance and memory usage.
This means that you must be careful: Q3ValueList does not know
diff --git a/src/qt3support/tools/q3valuestack.qdoc b/src/qt3support/tools/q3valuestack.qdoc
index 4ad0d7d..6c2c57b 100644
--- a/src/qt3support/tools/q3valuestack.qdoc
+++ b/src/qt3support/tools/q3valuestack.qdoc
@@ -44,7 +44,7 @@
without removing it.
Example:
- \snippet doc/src/snippets/code/doc_src_q3valuestack.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3valuestack.cpp 0
Q3ValueStack is a specialized Q3ValueList provided for convenience.
All of Q3ValueList's functionality also applies to Q3PtrStack, for
diff --git a/src/qt3support/tools/q3valuevector.qdoc b/src/qt3support/tools/q3valuevector.qdoc
index 58bd8e3..960bbac 100644
--- a/src/qt3support/tools/q3valuevector.qdoc
+++ b/src/qt3support/tools/q3valuevector.qdoc
@@ -70,10 +70,10 @@
objects it contains.
Example:
- \snippet doc/src/snippets/code/doc_src_q3valuevector.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_q3valuevector.cpp 0
Program output:
- \snippet doc/src/snippets/code/doc_src_q3valuevector.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_q3valuevector.cpp 1
As you can see, the most recent change to Joe's salary did not
affect the value in the vector because the vector created a copy
@@ -102,13 +102,13 @@
an element that does not exist (your application will probably
crash). For example:
- \snippet doc/src/snippets/code/doc_src_q3valuevector.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_q3valuevector.cpp 2
Whenever inserting, removing or referencing elements in a vector,
always make sure you are referring to valid positions. For
example:
- \snippet doc/src/snippets/code/doc_src_q3valuevector.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_q3valuevector.cpp 3
The iterators provided by vector are random access iterators,
therefore you can use them with many generic algorithms, for
@@ -127,7 +127,7 @@
application will crash or do unpredictable things). Use back() and
front() with caution, for example:
- \snippet doc/src/snippets/code/doc_src_q3valuevector.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_q3valuevector.cpp 4
Because Q3ValueVector manages memory dynamically, it is recommended
that you contruct a vector with an initial size. Inserting and
diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index a41f784..26a0761 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -12952,4 +12952,33 @@ EXPORTS
?isWordSelectionEnabled@QTextControl@@QBE_NXZ @ 12951 NONAME ; bool QTextControl::isWordSelectionEnabled(void) const
?assignedInputContext@QWidgetPrivate@@QBEPAVQInputContext@@XZ @ 12952 NONAME ; class QInputContext * QWidgetPrivate::assignedInputContext(void) const
?updateMicroFocus@QLineControl@@IAEXXZ @ 12953 NONAME ; void QLineControl::updateMicroFocus(void)
+ ?beginDataAccess@QVolatileImage@@QBEXXZ @ 12954 NONAME ; void QVolatileImage::beginDataAccess(void) const
+ ??1QVolatileImage@@QAE@XZ @ 12955 NONAME ; QVolatileImage::~QVolatileImage(void)
+ ??0QVolatileImage@@QAE@HHW4Format@QImage@@@Z @ 12956 NONAME ; QVolatileImage::QVolatileImage(int, int, enum QImage::Format)
+ ?ensureFormat@QVolatileImage@@QAE_NW4Format@QImage@@@Z @ 12957 NONAME ; bool QVolatileImage::ensureFormat(enum QImage::Format)
+ ?fill@QVolatileImage@@QAEXI@Z @ 12958 NONAME ; void QVolatileImage::fill(unsigned int)
+ ?isNull@QVolatileImage@@QBE_NXZ @ 12959 NONAME ; bool QVolatileImage::isNull(void) const
+ ?toImage@QVolatileImage@@QBE?AVQImage@@XZ @ 12960 NONAME ; class QImage QVolatileImage::toImage(void) const
+ ??0QVolatileImage@@QAE@ABVQImage@@@Z @ 12961 NONAME ; QVolatileImage::QVolatileImage(class QImage const &)
+ ?format@QVolatileImage@@QBE?AW4Format@QImage@@XZ @ 12962 NONAME ; enum QImage::Format QVolatileImage::format(void) const
+ ?endDataAccess@QVolatileImage@@QBEX_N@Z @ 12963 NONAME ; void QVolatileImage::endDataAccess(bool) const
+ ?constBits@QVolatileImage@@QBEPBEXZ @ 12964 NONAME ; unsigned char const * QVolatileImage::constBits(void) const
+ ?height@QVolatileImage@@QBEHXZ @ 12965 NONAME ; int QVolatileImage::height(void) const
+ ?duplicateNativeImage@QVolatileImage@@QBEPAXXZ @ 12966 NONAME ; void * QVolatileImage::duplicateNativeImage(void) const
+ ?bits@QVolatileImage@@QAEPAEXZ @ 12967 NONAME ; unsigned char * QVolatileImage::bits(void)
+ ?paintEngine@QVolatileImage@@QAEPAVQPaintEngine@@XZ @ 12968 NONAME ; class QPaintEngine * QVolatileImage::paintEngine(void)
+ ?bytesPerLine@QVolatileImage@@QBEHXZ @ 12969 NONAME ; int QVolatileImage::bytesPerLine(void) const
+ ?width@QVolatileImage@@QBEHXZ @ 12970 NONAME ; int QVolatileImage::width(void) const
+ ?copyFrom@QVolatileImage@@QAEXPAV1@ABVQRect@@@Z @ 12971 NONAME ; void QVolatileImage::copyFrom(class QVolatileImage *, class QRect const &)
+ ?imageRef@QVolatileImage@@QAEAAVQImage@@XZ @ 12972 NONAME ; class QImage & QVolatileImage::imageRef(void)
+ ??0QVolatileImage@@QAE@PAX0@Z @ 12973 NONAME ; QVolatileImage::QVolatileImage(void *, void *)
+ ??4QVolatileImage@@QAEAAV0@ABV0@@Z @ 12974 NONAME ; class QVolatileImage & QVolatileImage::operator=(class QVolatileImage const &)
+ ??0QVolatileImage@@QAE@XZ @ 12975 NONAME ; QVolatileImage::QVolatileImage(void)
+ ?hasAlphaChannel@QVolatileImage@@QBE_NXZ @ 12976 NONAME ; bool QVolatileImage::hasAlphaChannel(void) const
+ ?setAlphaChannel@QVolatileImage@@QAEXABVQPixmap@@@Z @ 12977 NONAME ; void QVolatileImage::setAlphaChannel(class QPixmap const &)
+ ?byteCount@QVolatileImage@@QBEHXZ @ 12978 NONAME ; int QVolatileImage::byteCount(void) const
+ ??0QVolatileImage@@QAE@ABV0@@Z @ 12979 NONAME ; QVolatileImage::QVolatileImage(class QVolatileImage const &)
+ ?depth@QVolatileImage@@QBEHXZ @ 12980 NONAME ; int QVolatileImage::depth(void) const
+ ?releaseCachedResources@QGraphicsSystem@@UAEXXZ @ 12981 NONAME ; void QGraphicsSystem::releaseCachedResources(void)
+ ?qt_s60_setPartialScreenInputMode@@YAX_N@Z @ 12982 NONAME ; void qt_s60_setPartialScreenInputMode(bool)
diff --git a/src/s60installs/bwins/QtOpenGLu.def b/src/s60installs/bwins/QtOpenGLu.def
index 620fcb9..d7c8394 100644
--- a/src/s60installs/bwins/QtOpenGLu.def
+++ b/src/s60installs/bwins/QtOpenGLu.def
@@ -703,4 +703,23 @@ EXPORTS
?maxTextureWidth@QGLTextureGlyphCache@@UBEHXZ @ 702 NONAME ; int QGLTextureGlyphCache::maxTextureWidth(void) const
?filterMode@QGLTextureGlyphCache@@QBE?AW4FilterMode@1@XZ @ 703 NONAME ; enum QGLTextureGlyphCache::FilterMode QGLTextureGlyphCache::filterMode(void) const
?setFilterMode@QGLTextureGlyphCache@@QAEXW4FilterMode@1@@Z @ 704 NONAME ; void QGLTextureGlyphCache::setFilterMode(enum QGLTextureGlyphCache::FilterMode)
+ ?toNativeType@QGLPixmapData@@UAEPAXW4NativeType@QPixmapData@@@Z @ 705 NONAME ; void * QGLPixmapData::toNativeType(enum QPixmapData::NativeType)
+ ?fromNativeType@QGLPixmapData@@UAEXPAXW4NativeType@QPixmapData@@@Z @ 706 NONAME ; void QGLPixmapData::fromNativeType(void *, enum QPixmapData::NativeType)
+ ?clear@QGLTextureGlyphCache@@QAEXXZ @ 707 NONAME ; void QGLTextureGlyphCache::clear(void)
+ ?context@QGLTextureGlyphCache@@QBEPAVQGLContext@@XZ @ 708 NONAME ; class QGLContext * QGLTextureGlyphCache::context(void) const
+ ?swapBehavior@QGLWindowSurface@@2W4SwapMode@1@A @ 709 NONAME ; enum QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior
+ ?createPixmapForImage@QGLPixmapData@@AAEXAAVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@_N@Z @ 710 NONAME ; void QGLPixmapData::createPixmapForImage(class QImage &, class QFlags<enum Qt::ImageConversionFlag>, bool)
+ ?fromImageReader@QGLPixmapData@@UAEXPAVQImageReader@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 711 NONAME ; void QGLPixmapData::fromImageReader(class QImageReader *, class QFlags<enum Qt::ImageConversionFlag>)
+ ?setContext@QGLTextureGlyphCache@@QAEXPAVQGLContext@@@Z @ 712 NONAME ; void QGLTextureGlyphCache::setContext(class QGLContext *)
+ ?hibernate@QGLPixmapData@@QAEXXZ @ 713 NONAME ; void QGLPixmapData::hibernate(void)
+ ?detachTextureFromPool@QGLPixmapData@@QAEXXZ @ 714 NONAME ; void QGLPixmapData::detachTextureFromPool(void)
+ ?reclaimTexture@QGLPixmapData@@QAEXXZ @ 715 NONAME ; void QGLPixmapData::reclaimTexture(void)
+ ?destroyTexture@QGLPixmapData@@QAEXXZ @ 716 NONAME ; void QGLPixmapData::destroyTexture(void)
+ ?releaseCachedResources@QGLGraphicsSystem@@UAEXXZ @ 717 NONAME ; void QGLGraphicsSystem::releaseCachedResources(void)
+ ?serialNumber@QGLTextureGlyphCache@@QBEHXZ @ 718 NONAME ; int QGLTextureGlyphCache::serialNumber(void) const
+ ?forceToImage@QGLPixmapData@@QAEXXZ @ 719 NONAME ; void QGLPixmapData::forceToImage(void)
+ ?idealFormat@QGLPixmapData@@QAE?AW4Format@QImage@@AAV3@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 720 NONAME ; enum QImage::Format QGLPixmapData::idealFormat(class QImage &, class QFlags<enum Qt::ImageConversionFlag>)
+ ?releaseNativeImageHandle@QGLPixmapData@@QAEXXZ @ 721 NONAME ; void QGLPixmapData::releaseNativeImageHandle(void)
+ ?createFromNativeImageHandleProvider@QGLPixmapData@@QAEXXZ @ 722 NONAME ; void QGLPixmapData::createFromNativeImageHandleProvider(void)
+ ?initFromNativeImageHandle@QGLPixmapData@@QAE_NPAXABVQString@@@Z @ 723 NONAME ; bool QGLPixmapData::initFromNativeImageHandle(void *, class QString const &)
diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def
index 87b9c7f..f2433d6 100644
--- a/src/s60installs/bwins/QtOpenVGu.def
+++ b/src/s60installs/bwins/QtOpenVGu.def
@@ -134,7 +134,7 @@ EXPORTS
?drawTextItem@QVGPaintEngine@@UAEXABVQPointF@@ABVQTextItem@@@Z @ 133 NONAME ; void QVGPaintEngine::drawTextItem(class QPointF const &, class QTextItem const &)
?clearScissor@QVGCompositionHelper@@QAEXXZ @ 134 NONAME ; void QVGCompositionHelper::clearScissor(void)
?fill@QVGPaintEngine@@UAEXABVQVectorPath@@ABVQBrush@@@Z @ 135 NONAME ; void QVGPaintEngine::fill(class QVectorPath const &, class QBrush const &)
- ?forceToImage@QVGPixmapData@@IAEXXZ @ 136 NONAME ; void QVGPixmapData::forceToImage(void)
+ ?forceToImage@QVGPixmapData@@IAEXXZ @ 136 NONAME ABSENT ; void QVGPixmapData::forceToImage(void)
?drawPoints@QVGPaintEngine@@UAEXPBVQPoint@@H@Z @ 137 NONAME ; void QVGPaintEngine::drawPoints(class QPoint const *, int)
??_EQVGPaintEngine@@UAE@I@Z @ 138 NONAME ; QVGPaintEngine::~QVGPaintEngine(unsigned int)
?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation)
@@ -176,4 +176,12 @@ EXPORTS
?fromData@QVGPixmapData@@UAE_NPBEIPBDV?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 175 NONAME ; bool QVGPixmapData::fromData(unsigned char const *, unsigned int, char const *, class QFlags<enum Qt::ImageConversionFlag>)
?fromImageReader@QVGPixmapData@@UAEXPAVQImageReader@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 176 NONAME ; void QVGPixmapData::fromImageReader(class QImageReader *, class QFlags<enum Qt::ImageConversionFlag>)
?canVgWritePixels@QVGPaintEngine@@ABE_NABVQImage@@@Z @ 177 NONAME ; bool QVGPaintEngine::canVgWritePixels(class QImage const &) const
+ ?updateSerial@QVGPixmapData@@IAEXXZ @ 178 NONAME ; void QVGPixmapData::updateSerial(void)
+ ?copy@QVGPixmapData@@UAEXPBVQPixmapData@@ABVQRect@@@Z @ 179 NONAME ; void QVGPixmapData::copy(class QPixmapData const *, class QRect const &)
+ ?idealFormat@QVGPixmapData@@IBE?AW4Format@QImage@@PAV3@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 180 NONAME ; enum QImage::Format QVGPixmapData::idealFormat(class QImage *, class QFlags<enum Qt::ImageConversionFlag>) const
+ ?ensureReadback@QVGPixmapData@@UBEX_N@Z @ 181 NONAME ; void QVGPixmapData::ensureReadback(bool) const
+ ?initFromNativeImageHandle@QVGPixmapData@@QAE_NPAXABVQString@@@Z @ 182 NONAME ; bool QVGPixmapData::initFromNativeImageHandle(void *, class QString const &)
+ ?createFromNativeImageHandleProvider@QVGPixmapData@@QAEXXZ @ 183 NONAME ; void QVGPixmapData::createFromNativeImageHandleProvider(void)
+ ?releaseNativeImageHandle@QVGPixmapData@@QAEXXZ @ 184 NONAME ; void QVGPixmapData::releaseNativeImageHandle(void)
+ ?forceToImage@QVGPixmapData@@IAEX_N@Z @ 185 NONAME ; void QVGPixmapData::forceToImage(bool)
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 2de88f2..799ac43 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -12147,4 +12147,41 @@ EXPORTS
_ZNK12QTextControl22isWordSelectionEnabledEv @ 12146 NONAME
_ZN12QLineControl16updateMicroFocusEv @ 12147 NONAME
_ZNK14QWidgetPrivate20assignedInputContextEv @ 12148 NONAME
+ _ZN14QVolatileImage11paintEngineEv @ 12149 NONAME
+ _ZN14QVolatileImage12ensureFormatEN6QImage6FormatE @ 12150 NONAME
+ _ZN14QVolatileImage15setAlphaChannelERK7QPixmap @ 12151 NONAME
+ _ZN14QVolatileImage4bitsEv @ 12152 NONAME
+ _ZN14QVolatileImage4fillEj @ 12153 NONAME
+ _ZN14QVolatileImage8copyFromEPS_RK5QRect @ 12154 NONAME
+ _ZN14QVolatileImage8imageRefEv @ 12155 NONAME
+ _ZN14QVolatileImageC1EPvS0_ @ 12156 NONAME
+ _ZN14QVolatileImageC1ERK6QImage @ 12157 NONAME
+ _ZN14QVolatileImageC1ERKS_ @ 12158 NONAME
+ _ZN14QVolatileImageC1EiiN6QImage6FormatE @ 12159 NONAME
+ _ZN14QVolatileImageC1Ev @ 12160 NONAME
+ _ZN14QVolatileImageC2EPvS0_ @ 12161 NONAME
+ _ZN14QVolatileImageC2ERK6QImage @ 12162 NONAME
+ _ZN14QVolatileImageC2ERKS_ @ 12163 NONAME
+ _ZN14QVolatileImageC2EiiN6QImage6FormatE @ 12164 NONAME
+ _ZN14QVolatileImageC2Ev @ 12165 NONAME
+ _ZN14QVolatileImageD1Ev @ 12166 NONAME
+ _ZN14QVolatileImageD2Ev @ 12167 NONAME
+ _ZN14QVolatileImageaSERKS_ @ 12168 NONAME
+ _ZNK14QVolatileImage12bytesPerLineEv @ 12169 NONAME
+ _ZNK14QVolatileImage13endDataAccessEb @ 12170 NONAME
+ _ZNK14QVolatileImage15beginDataAccessEv @ 12171 NONAME
+ _ZNK14QVolatileImage15hasAlphaChannelEv @ 12172 NONAME
+ _ZNK14QVolatileImage20duplicateNativeImageEv @ 12173 NONAME
+ _ZNK14QVolatileImage5depthEv @ 12174 NONAME
+ _ZNK14QVolatileImage5widthEv @ 12175 NONAME
+ _ZNK14QVolatileImage6formatEv @ 12176 NONAME
+ _ZNK14QVolatileImage6heightEv @ 12177 NONAME
+ _ZNK14QVolatileImage6isNullEv @ 12178 NONAME
+ _ZNK14QVolatileImage7toImageEv @ 12179 NONAME
+ _ZNK14QVolatileImage9byteCountEv @ 12180 NONAME
+ _ZNK14QVolatileImage9constBitsEv @ 12181 NONAME
+ _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12182 NONAME
+ _Z32qt_s60_setPartialScreenInputModeb @ 12183 NONAME
+ _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12184 NONAME
+ _ZNK10QTextBlock7isValidEv @ 12185 NONAME
diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def
index c92d99e..488c6cd 100644
--- a/src/s60installs/eabi/QtOpenGLu.def
+++ b/src/s60installs/eabi/QtOpenGLu.def
@@ -707,4 +707,21 @@ EXPORTS
_ZNK20QGLTextureGlyphCache16maxTextureHeightEv @ 706 NONAME
_ZThn8_NK20QGLTextureGlyphCache15maxTextureWidthEv @ 707 NONAME
_ZThn8_NK20QGLTextureGlyphCache16maxTextureHeightEv @ 708 NONAME
+ _ZN13QGLPixmapData12toNativeTypeEN11QPixmapData10NativeTypeE @ 709 NONAME
+ _ZN13QGLPixmapData14fromNativeTypeEPvN11QPixmapData10NativeTypeE @ 710 NONAME
+ _ZN13QGLPixmapData15fromImageReaderEP12QImageReader6QFlagsIN2Qt19ImageConversionFlagEE @ 711 NONAME
+ _ZN13QGLPixmapData20createPixmapForImageER6QImage6QFlagsIN2Qt19ImageConversionFlagEEb @ 712 NONAME
+ _ZN16QGLWindowSurface12swapBehaviorE @ 713 NONAME DATA 4
+ _ZN20QGLTextureGlyphCache10setContextEP10QGLContext @ 714 NONAME
+ _ZN20QGLTextureGlyphCache5clearEv @ 715 NONAME
+ _ZN13QGLPixmapData12forceToImageEv @ 716 NONAME
+ _ZN13QGLPixmapData14destroyTextureEv @ 717 NONAME
+ _ZN13QGLPixmapData14reclaimTextureEv @ 718 NONAME
+ _ZN13QGLPixmapData21detachTextureFromPoolEv @ 719 NONAME
+ _ZN13QGLPixmapData9hibernateEv @ 720 NONAME
+ _ZN17QGLGraphicsSystem22releaseCachedResourcesEv @ 721 NONAME
+ _ZN13QGLPixmapData11idealFormatER6QImage6QFlagsIN2Qt19ImageConversionFlagEE @ 722 NONAME
+ _ZN13QGLPixmapData24releaseNativeImageHandleEv @ 723 NONAME
+ _ZN13QGLPixmapData25initFromNativeImageHandleEPvRK7QString @ 724 NONAME
+ _ZN13QGLPixmapData35createFromNativeImageHandleProviderEv @ 725 NONAME
diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def
index e1828c1..08afd61 100644
--- a/src/s60installs/eabi/QtOpenVGu.def
+++ b/src/s60installs/eabi/QtOpenVGu.def
@@ -8,7 +8,7 @@ EXPORTS
_Z25qt_vg_create_paint_enginev @ 7 NONAME
_Z26qt_vg_destroy_paint_engineP14QVGPaintEngine @ 8 NONAME
_Z28qt_vg_config_to_image_formatP11QEglContext @ 9 NONAME
- _ZN13QVGPixmapData12forceToImageEv @ 10 NONAME
+ _ZN13QVGPixmapData12forceToImageEv @ 10 NONAME ABSENT
_ZN13QVGPixmapData12toNativeTypeEN11QPixmapData10NativeTypeE @ 11 NONAME
_ZN13QVGPixmapData14fromNativeTypeEPvN11QPixmapData10NativeTypeE @ 12 NONAME
_ZN13QVGPixmapData15setAlphaChannelERK7QPixmap @ 13 NONAME
@@ -206,4 +206,12 @@ EXPORTS
_ZN13QVGPixmapData8fromDataEPKhjPKc6QFlagsIN2Qt19ImageConversionFlagEE @ 205 NONAME
_ZN13QVGPixmapData8fromFileERK7QStringPKc6QFlagsIN2Qt19ImageConversionFlagEE @ 206 NONAME
_ZNK14QVGPaintEngine16canVgWritePixelsERK6QImage @ 207 NONAME
+ _ZN13QVGPixmapData12updateSerialEv @ 208 NONAME
+ _ZN13QVGPixmapData4copyEPK11QPixmapDataRK5QRect @ 209 NONAME
+ _ZNK13QVGPixmapData11idealFormatEP6QImage6QFlagsIN2Qt19ImageConversionFlagEE @ 210 NONAME
+ _ZNK13QVGPixmapData14ensureReadbackEb @ 211 NONAME
+ _ZN13QVGPixmapData24releaseNativeImageHandleEv @ 212 NONAME
+ _ZN13QVGPixmapData25initFromNativeImageHandleEPvRK7QString @ 213 NONAME
+ _ZN13QVGPixmapData35createFromNativeImageHandleProviderEv @ 214 NONAME
+ _ZN13QVGPixmapData12forceToImageEb @ 215 NONAME
diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby
index 4afbf05..d6b36e0 100644
--- a/src/s60installs/qt.iby
+++ b/src/s60installs/qt.iby
@@ -15,7 +15,6 @@ file=ABI_DIR\BUILD_DIR\QtXml.dll SHARED_LIB_DIR\QtXml.dll
file=ABI_DIR\BUILD_DIR\QtNetwork.dll SHARED_LIB_DIR\QtNetwork.dll
file=ABI_DIR\BUILD_DIR\QtScript.dll SHARED_LIB_DIR\QtScript.dll
file=ABI_DIR\BUILD_DIR\QtTest.dll SHARED_LIB_DIR\QtTest.dll
-file=ABI_DIR\BUILD_DIR\QtWebKit.dll SHARED_LIB_DIR\QtWebKit.dll
file=ABI_DIR\BUILD_DIR\phonon.dll SHARED_LIB_DIR\phonon.dll
file=ABI_DIR\BUILD_DIR\QtMultimedia.dll SHARED_LIB_DIR\QtMultimedia.dll
file=ABI_DIR\BUILD_DIR\QtXmlPatterns.dll SHARED_LIB_DIR\QtXmlPatterns.dll
@@ -40,14 +39,8 @@ file=ABI_DIR\BUILD_DIR\qtwcodecs.dll SHARED_LIB_DIR\qtwcodecs.dll
file=ABI_DIR\BUILD_DIR\qsvgicon.dll SHARED_LIB_DIR\qsvgicon.dll
// Phonon MMF backend
-// This is commented out by default, as normally Helix backend will be used.
-// If the Helix backend is present, it will override MMF backend, so make sure to remove it from
-// image creation in addition to uncommenting the following lines if you want to use MMF backend.
-//file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll
-//data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
-
-// QtMultimedia audio backend
-file=ABI_DIR\BUILD_DIR\qaudio.dll SHARED_LIB_DIR\qaudio.dll
+file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll
+data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
// graphicssystems
file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll
@@ -60,8 +53,6 @@ file=ABI_DIR\BUILD_DIR\qsymbianbearer.dll SHARED_LIB_DIR\qsymbianbearer.dll
// so don't bother including those plugins
file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll
-S60_APP_RESOURCE(s60main)
-
// imageformats stubs
data=\epoc32\data\z\resource\qt\plugins\imageformats\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin
data=\epoc32\data\z\resource\qt\plugins\imageformats\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin
@@ -80,24 +71,18 @@ data=\epoc32\data\z\resource\qt\plugins\codecs\qtwcodecs.qtplugin resou
data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin
// qml import plugins
-file=ABI_DIR\BUILD_DIR\qmlwebkitplugin.dll SHARED_LIB_DIR\qmlwebkitplugin.dll
file=ABI_DIR\BUILD_DIR\qmlfolderlistmodelplugin.dll SHARED_LIB_DIR\qmlfolderlistmodelplugin.dll
file=ABI_DIR\BUILD_DIR\qmlgesturesplugin.dll SHARED_LIB_DIR\qmlgesturesplugin.dll
file=ABI_DIR\BUILD_DIR\qmlparticlesplugin.dll SHARED_LIB_DIR\qmlparticlesplugin.dll
-data=\epoc32\data\z\resource\qt\imports\QtWebKit\qmlwebkitplugin.qtplugin resource\qt\imports\QtWebKit\qmlwebkitplugin.qtplugin
data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin
data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin
data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin
-data=\epoc32\data\z\resource\qt\imports\QtWebKit\qmldir resource\qt\imports\QtWebKit\qmldir
data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmldir resource\qt\imports\Qt\labs\folderlistmodel\qmldir
data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmldir resource\qt\imports\Qt\labs\gestures\qmldir
data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmldir resource\qt\imports\Qt\labs\particles\qmldir
-// QtMultimedia audio backend
-data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio\qaudio.qtplugin
-
// graphicssystems
data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin
data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin
@@ -107,7 +92,6 @@ data=\epoc32\data\z\resource\qt\plugins\bearer\qsymbianbearer.qtplugin resource\
// Stub sis file
data=ZSYSTEM\install\qt_stub.sis System\Install\qt_stub.sis
-data=ZSYSTEM\install\qtwebkit_stub.sis System\Install\qtwebkit_stub.sis
#endif // __QT_IBY__
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 1e5ce0f..d1bb48b 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -42,7 +42,7 @@ symbian: {
contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
qts60plugindeployment = \
- "IF package(0x20022E6D)" \
+ "IF package(0x2003A678) OR package(0x20022E6D)" \
" \"$$pluginLocations/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \
" \"$$bearerPluginLocation/qsymbianbearer$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qsymbianbearer$${QT_LIBINFIX}.dll\"" \
"ELSEIF package(0x1028315F)" \
@@ -58,7 +58,7 @@ symbian: {
" \"$$pluginLocations/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \
" \"$$bearerPluginLocation/qsymbianbearer$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qsymbianbearer$${QT_LIBINFIX}.dll\"" \
"ENDIF" \
- " \"$$bearerStubZ\" - \"c:$$replace(QT_PLUGINS_BASE_DIR,/,\\)\\bearer\\qsymbianbearer$${QT_LIBINFIX}.qtplugin\"
+ " \"$$bearerStubZ\" - \"c:$$replace(QT_PLUGINS_BASE_DIR,/,\\)\\bearer\\qsymbianbearer$${QT_LIBINFIX}.qtplugin\""
} else {
# No need to deploy plugins for older platform versions when building on Symbian3 or later
qts60plugindeployment = \
diff --git a/src/s60main/s60main.pro b/src/s60main/s60main.pro
index 8ab3bd3..1e3e06a 100644
--- a/src/s60main/s60main.pro
+++ b/src/s60main/s60main.pro
@@ -30,7 +30,7 @@ symbian {
# Having MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA will cause s60main.lib be unlinkable
# against GCCE apps, so remove it
MMP_RULES -= $$MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA
- linux-armcc:QMAKE_CXXFLAGS *= --export_all_vtbl
+ symbian-armcc:QMAKE_CXXFLAGS *= --export_all_vtbl
# Flag if exports are not frozen to avoid lookup of qtcore allocator creation function by ordinal
contains(CONFIG, def_files_disabled): DEFINES += QT_EXPORTS_NOT_FROZEN
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index 2468a46..5454df5 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -268,8 +268,14 @@ QScriptValue QScriptContext::argument(int index) const
QScriptValue QScriptContext::callee() const
{
const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
- QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
- return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee());
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame);
+ QScript::APIShim shim(eng);
+ if (frame->callee() == eng->originalGlobalObject()) {
+ // This is a pushContext()-created context; the callee is a lie.
+ Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext);
+ return QScriptValue();
+ }
+ return eng->scriptValueFromJSCValue(frame->callee());
}
/*!
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index d3e5f2f..160058e 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -955,8 +955,11 @@ static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng)
} // namespace QScript
QScriptEnginePrivate::QScriptEnginePrivate()
- : registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
- registeredScriptStrings(0), inEval(false)
+ : originalGlobalObjectProxy(0), currentFrame(0),
+ qobjectPrototype(0), qmetaobjectPrototype(0), variantPrototype(0),
+ activeAgent(0), agentLineNumber(-1),
+ registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
+ registeredScriptStrings(0), processEventsInterval(-1), inEval(false)
{
qMetaTypeId<QScriptValue>();
qMetaTypeId<QList<int> >();
@@ -1002,10 +1005,6 @@ QScriptEnginePrivate::QScriptEnginePrivate()
currentFrame = exec;
- originalGlobalObjectProxy = 0;
- activeAgent = 0;
- agentLineNumber = -1;
- processEventsInterval = -1;
cachedTranslationUrl = JSC::UString();
cachedTranslationContext = JSC::UString();
JSC::setCurrentIdentifierTable(oldTable);
@@ -1253,10 +1252,12 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
{
Q_Q(QScriptEngine);
- markStack.append(originalGlobalObject());
- markStack.append(globalObject());
- if (originalGlobalObjectProxy)
- markStack.append(originalGlobalObjectProxy);
+ if (originalGlobalObject()) {
+ markStack.append(originalGlobalObject());
+ markStack.append(globalObject());
+ if (originalGlobalObjectProxy)
+ markStack.append(originalGlobalObjectProxy);
+ }
if (qobjectPrototype)
markStack.append(qobjectPrototype);
@@ -1281,7 +1282,7 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
}
}
- {
+ if (q) {
QScriptContext *context = q->currentContext();
while (context) {
@@ -2727,6 +2728,14 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV
bool clearScopeChain)
{
JSC::JSValue thisObject = _thisObject;
+ if (!callee) {
+ // callee can't be zero, as this can cause JSC to crash during GC
+ // marking phase if the context's Arguments object has been created.
+ // Fake it by using the global object. Note that this is also handled
+ // in QScriptContext::callee(), as that function should still return
+ // an invalid value.
+ callee = originalGlobalObject();
+ }
if (calledAsConstructor) {
//JSC doesn't create default created object for native functions. so we do it
JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype);
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index ac57918..e289636 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -254,6 +254,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, int val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -271,6 +272,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, uint val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -288,6 +290,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsNumber(exec, val));
} else
@@ -305,6 +308,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
@@ -325,6 +329,7 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const char *val)
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
{
if (engine) {
+ QScript::APIShim shim(d_ptr->engine);
JSC::ExecState *exec = d_ptr->engine->currentFrame;
d_ptr->initFrom(JSC::jsString(exec, val));
} else {
diff --git a/src/src.pro b/src/src.pro
index 060f48b..868e22f 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -108,7 +108,7 @@ src_webkit_declarative.target = sub-webkitdeclarative
src_phonon.depends = src_gui
src_multimedia.depends = src_gui
contains(QT_CONFIG, opengl):src_multimedia.depends += src_opengl
- src_tools_activeqt.depends = src_tools_idc src_gui
+ src_activeqt.depends = src_tools_idc src_gui
src_declarative.depends = src_gui src_script src_network
src_plugins.depends = src_gui src_sql src_svg
contains(QT_CONFIG, multimedia):src_plugins.depends += src_multimedia
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 9698860..3fbc08c 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -584,7 +584,7 @@ static qreal toDouble(const QChar *&str)
++str;
}
bool exponent = false;
- if (*str == QLatin1Char('e') && pos < maxLen) {
+ if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) {
exponent = true;
temp[pos++] = 'e';
++str;
diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc
index 298b2b7..0c22868 100644
--- a/src/testlib/qsignalspy.qdoc
+++ b/src/testlib/qsignalspy.qdoc
@@ -38,7 +38,7 @@
The following example records all signal emissions for the \c clicked() signal
of a QCheckBox:
- \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 0
\c{spy.takeFirst()} returns the arguments for the first emitted signal, as a
list of QVariant objects. The \c clicked() signal has a single bool argument,
@@ -46,17 +46,17 @@
The example below catches a signal from a custom object:
- \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 1
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 1
\bold {Note:} Non-standard data types need to be registered, using
the qRegisterMetaType() function, before you can create a
QSignalSpy. For example:
- \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 2
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 2
To retrieve the \c QModelIndex, you can use qvariant_cast:
- \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 3
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 3
*/
/*! \fn QSignalSpy::QSignalSpy(QObject *object, const char *signal)
@@ -65,7 +65,7 @@
from the QObject \a object. Neither \a signal nor \a object can be null.
Example:
- \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 4
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.cpp 4
*/
/*! \fn QSignalSpy::isValid() const
diff --git a/src/testlib/qtestevent.qdoc b/src/testlib/qtestevent.qdoc
index 84e874b..4c695c2 100644
--- a/src/testlib/qtestevent.qdoc
+++ b/src/testlib/qtestevent.qdoc
@@ -39,7 +39,7 @@
QWidget.
Example:
- \snippet doc/src/snippets/code/doc_src_qtestevent.qdoc 0
+ \snippet doc/src/snippets/code/doc_src_qtestevent.cpp 0
The example above simulates the user entering the character \c a
followed by a backspace, waiting for 200 milliseconds and