summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/easing/easing.cpp22
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c4
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri2
-rw-r--r--src/3rdparty/webkit/ChangeLog10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/ChangeLog48
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h30
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog127
-rw-r--r--src/3rdparty/webkit/WebCore/WebCore.pro27
-rw-r--r--src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp15
-rw-r--r--src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h1
-rw-r--r--src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h2
-rw-r--r--src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h10
-rw-r--r--src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h49
-rw-r--r--src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp73
-rw-r--r--src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp5
-rw-r--r--src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h2
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp14
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp5
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp68
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebview.h5
-rw-r--r--src/3rdparty/webkit/WebKit/qt/ChangeLog130
-rw-r--r--src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp9
-rw-r--r--src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp4
-rw-r--r--src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro3
-rw-r--r--src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def (renamed from src/s60installs/bwins/QtWebKitu.def)0
-rw-r--r--src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def (renamed from src/s60installs/eabi/QtWebKitu.def)0
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp38
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp15
-rw-r--r--src/activeqt/container/qaxbase.cpp2
-rw-r--r--src/corelib/animation/qvariantanimation.cpp7
-rw-r--r--src/corelib/codecs/qiconvcodec.cpp4
-rw-r--r--src/corelib/codecs/qtextcodec.h2
-rw-r--r--src/corelib/concurrent/qtconcurrentiteratekernel.cpp3
-rw-r--r--src/corelib/global/qglobal.cpp31
-rw-r--r--src/corelib/global/qglobal.h4
-rw-r--r--src/corelib/io/qdebug.h2
-rw-r--r--src/corelib/io/qfileinfo.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_dnotify.cpp11
-rw-r--r--src/corelib/io/qfsfileengine.cpp16
-rw-r--r--src/corelib/io/qfsfileengine_p.h2
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp37
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp9
-rw-r--r--src/corelib/io/qprocess.cpp3
-rw-r--r--src/corelib/io/qresource.cpp2
-rw-r--r--src/corelib/io/qtextstream.cpp9
-rw-r--r--src/corelib/io/qurl.cpp14
-rw-r--r--src/corelib/kernel/qcore_unix.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp81
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/kernel/qmath.h169
-rw-r--r--src/corelib/kernel/qmetaobject.cpp1
-rw-r--r--src/corelib/kernel/qobject.cpp76
-rw-r--r--src/corelib/kernel/qobject.h6
-rw-r--r--src/corelib/kernel/qobject_p.h11
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/thread/qthread_p.h2
-rw-r--r--src/corelib/thread/qthread_unix.cpp4
-rw-r--r--src/corelib/thread/qthreadstorage.cpp97
-rw-r--r--src/corelib/tools/qcache.h3
-rw-r--r--src/corelib/tools/qhash.h8
-rw-r--r--src/corelib/tools/qline.cpp4
-rw-r--r--src/corelib/tools/qlocale.cpp8
-rw-r--r--src/corelib/tools/qregexp.h2
-rw-r--r--src/corelib/tools/qtimeline.cpp2
-rw-r--r--src/corelib/tools/qvector.h2
-rw-r--r--src/dbus/qdbusabstractinterface.cpp10
-rw-r--r--src/dbus/qdbusargument_p.h2
-rw-r--r--src/dbus/qdbusconnection.cpp4
-rw-r--r--src/dbus/qdbusconnection_p.h24
-rw-r--r--src/dbus/qdbusconnectioninterface.cpp2
-rw-r--r--src/dbus/qdbuserror.cpp2
-rw-r--r--src/dbus/qdbusintegrator.cpp114
-rw-r--r--src/dbus/qdbusintegrator_p.h2
-rw-r--r--src/dbus/qdbusinterface.cpp2
-rw-r--r--src/dbus/qdbusinterface_p.h4
-rw-r--r--src/dbus/qdbusinternalfilters.cpp2
-rw-r--r--src/dbus/qdbusmarshaller.cpp4
-rw-r--r--src/dbus/qdbusmessage.cpp2
-rw-r--r--src/dbus/qdbusmetatype.cpp2
-rw-r--r--src/dbus/qdbuspendingcall.cpp2
-rw-r--r--src/dbus/qdbuspendingreply.h1
-rw-r--r--src/dbus/qdbusutil.cpp2
-rw-r--r--src/dbus/qdbusxmlparser_p.h2
-rw-r--r--src/gui/dialogs/dialogs.pri18
-rw-r--r--src/gui/dialogs/qcolordialog_mac.mm35
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm4
-rw-r--r--src/gui/dialogs/qmessagebox.cpp17
-rw-r--r--src/gui/effects/qgraphicseffect.cpp40
-rw-r--r--src/gui/effects/qgraphicseffect_p.h11
-rw-r--r--src/gui/egl/qegl.cpp5
-rw-r--r--src/gui/egl/qeglproperties.cpp9
-rw-r--r--src/gui/embedded/qscreen_qws.cpp1
-rw-r--r--src/gui/embedded/qscreen_qws.h2
-rw-r--r--src/gui/graphicsview/qgraph_p.h4
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp27
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp621
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h24
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp170
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h1
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h7
-rw-r--r--src/gui/graphicsview/qgraphicslayout.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp43
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp45
-rw-r--r--src/gui/graphicsview/qgraphicsview.h1
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h2
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp3
-rw-r--r--src/gui/graphicsview/qsimplex_p.h2
-rw-r--r--src/gui/image/qimage.h6
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp11
-rw-r--r--src/gui/image/qimagereader.cpp42
-rw-r--r--src/gui/image/qpixmap.cpp9
-rw-r--r--src/gui/image/qpixmap.h2
-rw-r--r--src/gui/image/qpixmap_raster.cpp2
-rw-r--r--src/gui/image/qpixmap_s60.cpp103
-rw-r--r--src/gui/image/qpixmap_s60_p.h6
-rw-r--r--src/gui/image/qpixmapcache.cpp5
-rw-r--r--src/gui/image/qpixmapfilter.cpp364
-rw-r--r--src/gui/image/qpnghandler.cpp5
-rw-r--r--src/gui/image/qppmhandler.cpp2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp7
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp36
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h1
-rw-r--r--src/gui/itemviews/qlistwidget.cpp5
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp33
-rw-r--r--src/gui/itemviews/qtreeview.cpp1
-rw-r--r--src/gui/kernel/kernel.pri3
-rw-r--r--src/gui/kernel/qapplication.cpp62
-rw-r--r--src/gui/kernel/qapplication_mac.mm5
-rw-r--r--src/gui/kernel/qapplication_s60.cpp170
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm140
-rw-r--r--src/gui/kernel/qcocoapanel_mac_p.h2
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h187
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm35
-rw-r--r--src/gui/kernel/qcocoawindow_mac.mm137
-rw-r--r--src/gui/kernel/qcocoawindow_mac_p.h8
-rw-r--r--src/gui/kernel/qevent.cpp8
-rw-r--r--src/gui/kernel/qgesturemanager.cpp42
-rw-r--r--src/gui/kernel/qgesturemanager_p.h4
-rw-r--r--src/gui/kernel/qguieventdispatcher_glib.cpp2
-rw-r--r--src/gui/kernel/qkeysequence.cpp6
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp13
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm45
-rw-r--r--src/gui/kernel/qt_s60_p.h14
-rw-r--r--src/gui/kernel/qwidget.cpp31
-rw-r--r--src/gui/kernel/qwidget.h1
-rw-r--r--src/gui/kernel/qwidget_mac.mm120
-rw-r--r--src/gui/kernel/qwidget_p.h2
-rw-r--r--src/gui/painting/painting.pri7
-rw-r--r--src/gui/painting/qbezier.cpp20
-rw-r--r--src/gui/painting/qbezier_p.h2
-rw-r--r--src/gui/painting/qblendfunctions.cpp2
-rw-r--r--src/gui/painting/qdrawhelper.cpp28
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp260
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h76
-rw-r--r--src/gui/painting/qmatrix.h2
-rw-r--r--src/gui/painting/qmemrotate.cpp21
-rw-r--r--src/gui/painting/qmemrotate_p.h2
-rw-r--r--src/gui/painting/qpaintdevice.h2
-rw-r--r--src/gui/painting/qpaintdevice.qdoc2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp180
-rw-r--r--src/gui/painting/qpathclipper.cpp2
-rw-r--r--src/gui/painting/qprinterinfo_unix.cpp50
-rw-r--r--src/gui/painting/qregion.h2
-rw-r--r--src/gui/painting/qstroker.cpp4
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h5
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp8
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/styles/qgtkstyle.cpp25
-rw-r--r--src/gui/styles/qgtkstyle_p.cpp6
-rw-r--r--src/gui/styles/qgtkstyle_p.h2
-rw-r--r--src/gui/styles/qs60style.cpp351
-rw-r--r--src/gui/styles/qs60style_p.h13
-rw-r--r--src/gui/styles/qs60style_s60.cpp817
-rw-r--r--src/gui/styles/qs60style_simulated.cpp5
-rw-r--r--src/gui/styles/qstylehelper.cpp2
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp2
-rw-r--r--src/gui/styles/qwindowsxpstyle.cpp16
-rw-r--r--src/gui/styles/styles.pri2
-rw-r--r--src/gui/text/qfontdatabase.cpp14
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp3
-rw-r--r--src/gui/text/qfontengine.cpp120
-rw-r--r--src/gui/text/qfontengine_mac.mm8
-rw-r--r--src/gui/text/qfontengine_p.h16
-rw-r--r--src/gui/text/qfontengineglyphcache_p.h7
-rw-r--r--src/gui/text/qtextcontrol.cpp6
-rw-r--r--src/gui/text/qtextdocument_p.cpp12
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp72
-rw-r--r--src/gui/util/qsystemtrayicon.cpp3
-rw-r--r--src/gui/util/qsystemtrayicon_mac.mm28
-rw-r--r--src/gui/util/qsystemtrayicon_p.h1
-rw-r--r--src/gui/util/qsystemtrayicon_win.cpp21
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp4
-rw-r--r--src/gui/widgets/qabstractspinbox.cpp69
-rw-r--r--src/gui/widgets/qabstractspinbox_p.h3
-rw-r--r--src/gui/widgets/qcombobox.cpp5
-rw-r--r--src/gui/widgets/qdial.cpp3
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp30
-rw-r--r--src/gui/widgets/qdockarealayout.cpp4
-rw-r--r--src/gui/widgets/qlcdnumber.h3
-rw-r--r--src/gui/widgets/qlinecontrol.cpp8
-rw-r--r--src/gui/widgets/qlineedit.cpp62
-rw-r--r--src/gui/widgets/qlineedit.h11
-rw-r--r--src/gui/widgets/qlineedit_p.cpp26
-rw-r--r--src/gui/widgets/qlineedit_p.h4
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm3
-rw-r--r--src/gui/widgets/qmenu.cpp35
-rw-r--r--src/gui/widgets/qmenu_p.h1
-rw-r--r--src/gui/widgets/qplaintextedit.cpp16
-rw-r--r--src/gui/widgets/qprintpreviewwidget.h2
-rw-r--r--src/gui/widgets/qpushbutton.cpp33
-rw-r--r--src/gui/widgets/qpushbutton_p.h4
-rw-r--r--src/gui/widgets/qtextedit.cpp4
-rw-r--r--src/gui/widgets/qtoolbar.cpp2
-rw-r--r--src/gui/widgets/qtoolbararealayout.cpp15
-rw-r--r--src/gui/widgets/qtoolbarlayout.cpp3
-rw-r--r--src/multimedia/audio/audio.pri5
-rw-r--r--src/multimedia/audio/qaudiodevicefactory.cpp14
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp5
-rw-r--r--src/multimedia/audio/qaudioinput.cpp15
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.cpp38
-rw-r--r--src/multimedia/audio/qaudiooutput.cpp15
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.cpp8
-rw-r--r--src/network/access/qnetworkreply.cpp2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp4
-rw-r--r--src/network/access/qnetworkrequest.cpp3
-rw-r--r--src/network/kernel/qhostinfo.cpp297
-rw-r--r--src/network/kernel/qhostinfo_p.h148
-rw-r--r--src/network/kernel/qhostinfo_win.cpp6
-rw-r--r--src/opengl/gl2paintengineex/qglcustomshaderstage_p.h2
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp198
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h66
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp418
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h98
-rw-r--r--src/opengl/gl2paintengineex/qtriangulatingstroker.cpp10
-rw-r--r--src/opengl/qgl.cpp602
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_egl.cpp34
-rw-r--r--src/opengl/qgl_p.h70
-rw-r--r--src/opengl/qgl_x11.cpp24
-rw-r--r--src/opengl/qgl_x11egl.cpp164
-rw-r--r--src/opengl/qglextensions_p.h17
-rw-r--r--src/opengl/qglframebufferobject.cpp10
-rw-r--r--src/opengl/qglpaintdevice.cpp10
-rw-r--r--src/opengl/qglpixmapfilter.cpp754
-rw-r--r--src/opengl/qglshaderprogram.cpp67
-rw-r--r--src/opengl/qglshaderprogram.h4
-rw-r--r--src/opengl/qpaintengine_opengl.cpp20
-rw-r--r--src/opengl/qpixmapdata_gl.cpp88
-rw-r--r--src/opengl/qpixmapdata_gl_p.h4
-rw-r--r--src/opengl/qwindowsurface_gl.cpp9
-rw-r--r--src/openvg/openvg.pro7
-rw-r--r--src/openvg/qpaintengine_vg.cpp16
-rw-r--r--src/openvg/qpixmapdata_vg.cpp129
-rw-r--r--src/openvg/qpixmapdata_vg_p.h46
-rw-r--r--src/openvg/qpixmapfilter_vg.cpp25
-rw-r--r--src/openvg/qvg_p.h10
-rw-r--r--src/openvg/qvgimagepool.cpp215
-rw-r--r--src/openvg/qvgimagepool_p.h157
-rw-r--r--src/openvg/qwindowsurface_vgegl.cpp128
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp76
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp4
-rw-r--r--src/plugins/imageformats/gif/qgifhandler.cpp40
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp407
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.h4
-rw-r--r--src/plugins/qpluginbase.pri2
-rw-r--r--src/plugins/sqldrivers/sqldrivers.pro4
-rw-r--r--src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro2
-rw-r--r--src/qbase.pri2
-rw-r--r--src/qt_install.pri6
-rw-r--r--src/s60installs/bwins/QtCoreu.def2
-rw-r--r--src/s60installs/bwins/QtGuiu.def38
-rw-r--r--src/s60installs/bwins/QtOpenVGu.def142
-rw-r--r--src/s60installs/eabi/QtCoreu.def2
-rw-r--r--src/s60installs/eabi/QtGuiu.def69
-rw-r--r--src/s60installs/eabi/QtOpenVGu.def12
-rw-r--r--src/s60installs/qt.iby26
-rw-r--r--src/s60installs/s60installs.pro9
-rw-r--r--src/s60main/qts60main.cpp58
-rw-r--r--src/s60main/qts60main_mcrt0.cpp52
-rw-r--r--src/script/api/qscriptengine.cpp28
-rw-r--r--src/script/bridge/qscriptqobject.cpp27
-rw-r--r--src/script/script.pro2
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp1
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp87
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp23
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp17
-rw-r--r--src/sql/kernel/qsqlcachedresult.cpp5
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp2
-rw-r--r--src/svg/qsvghandler.cpp36
-rw-r--r--src/svg/qsvgstyle.cpp4
-rw-r--r--src/tools/moc/generator.cpp11
-rw-r--r--src/xml/sax/qxml.cpp4
-rw-r--r--src/xmlpatterns/api/api.pri116
-rw-r--r--src/xmlpatterns/api/qcoloringmessagehandler.cpp198
-rw-r--r--src/xmlpatterns/api/qcoloringmessagehandler_p.h98
-rw-r--r--src/xmlpatterns/api/qcoloroutput.cpp348
-rw-r--r--src/xmlpatterns/api/qcoloroutput_p.h133
-rw-r--r--src/xmlpatterns/api/qxmlpatternistcli_p.h74
-rw-r--r--src/xmlpatterns/xmlpatterns.pro34
312 files changed, 8674 insertions, 4432 deletions
diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp
index 81af40f..7d70a4d 100644
--- a/src/3rdparty/easing/easing.cpp
+++ b/src/3rdparty/easing/easing.cpp
@@ -252,7 +252,7 @@ static qreal easeOutInQuint(qreal t)
*/
static qreal easeInSine(qreal t)
{
- return (t == 1.0) ? 1.0 : -::cos(t * M_PI_2) + 1.0;
+ return (t == 1.0) ? 1.0 : -::qCos(t * M_PI_2) + 1.0;
}
/**
@@ -263,7 +263,7 @@ static qreal easeInSine(qreal t)
*/
static qreal easeOutSine(qreal t)
{
- return ::sin(t* M_PI_2);
+ return ::qSin(t* M_PI_2);
}
/**
@@ -274,7 +274,7 @@ static qreal easeOutSine(qreal t)
*/
static qreal easeInOutSine(qreal t)
{
- return -0.5 * (::cos(M_PI*t) - 1);
+ return -0.5 * (::qCos(M_PI*t) - 1);
}
/**
@@ -397,15 +397,15 @@ static qreal easeInElastic_helper(qreal t, qreal b, qreal c, qreal d, qreal a, q
if (t_adj==1) return b+c;
qreal s;
- if(a < ::fabs(c)) {
+ if(a < ::qFabs(c)) {
a = c;
s = p / 4.0f;
} else {
- s = p / (2 * M_PI) * ::asin(c / a);
+ s = p / (2 * M_PI) * ::qAsin(c / a);
}
t_adj -= 1.0f;
- return -(a*::qPow(2.0f,10*t_adj) * ::sin( (t_adj*d-s)*(2*M_PI)/p )) + b;
+ return -(a*::qPow(2.0f,10*t_adj) * ::qSin( (t_adj*d-s)*(2*M_PI)/p )) + b;
}
/**
@@ -431,10 +431,10 @@ static qreal easeOutElastic_helper(qreal t, qreal /*b*/, qreal c, qreal /*d*/, q
a = c;
s = p / 4.0f;
} else {
- s = p / (2 * M_PI) * ::asin(c / a);
+ s = p / (2 * M_PI) * ::qAsin(c / a);
}
- return (a*::qPow(2.0f,-10*t) * ::sin( (t-s)*(2*M_PI)/p ) + c);
+ return (a*::qPow(2.0f,-10*t) * ::qSin( (t-s)*(2*M_PI)/p ) + c);
}
/**
@@ -469,11 +469,11 @@ static qreal easeInOutElastic(qreal t, qreal a, qreal p)
a = 1.0;
s = p / 4.0f;
} else {
- s = p / (2 * M_PI) * ::asin(1.0 / a);
+ s = p / (2 * M_PI) * ::qAsin(1.0 / a);
}
- if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p ));
- return a*::qPow(2.0f,-10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0;
+ if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::qSin( (t-1-s)*(2*M_PI)/p ));
+ return a*::qPow(2.0f,-10*(t-1)) * ::qSin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0;
}
/**
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
index 2bda386..67029be 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
@@ -56,8 +56,6 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
assert(shaper_item->item.script == HB_Script_Hebrew);
- HB_HeuristicSetGlyphAttributes(shaper_item);
-
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, hebrew_features)) {
@@ -65,7 +63,7 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
if (!HB_ConvertStringToGlyphIndices(shaper_item))
return FALSE;
-
+ HB_HeuristicSetGlyphAttributes(shaper_item);
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
index bfb03ab..bfc7bd4 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
@@ -980,6 +980,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
HB_Stream gdefStream;
gdefStream = getTableStream(font, tableFunc, TTAG_GDEF);
+ error = HB_Err_Not_Covered;
if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) {
//DEBUG("error loading gdef table: %d", error);
face->gdef = 0;
@@ -987,6 +988,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
//DEBUG() << "trying to load gsub table";
stream = getTableStream(font, tableFunc, TTAG_GSUB);
+ error = HB_Err_Not_Covered;
if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) {
face->gsub = 0;
if (error != HB_Err_Not_Covered) {
@@ -998,6 +1000,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
_hb_close_stream(stream);
stream = getTableStream(font, tableFunc, TTAG_GPOS);
+ error = HB_Err_Not_Covered;
if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) {
face->gpos = 0;
DEBUG("error loading gpos table: %d", error);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
index 28328e7..a6fb2f8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
@@ -39,10 +39,12 @@ win32-* {
contains(JAVASCRIPTCORE_JIT,yes) {
DEFINES+=ENABLE_JIT=1
DEFINES+=ENABLE_YARR_JIT=1
+ DEFINES+=ENABLE_YARR=1
}
contains(JAVASCRIPTCORE_JIT,no) {
DEFINES+=ENABLE_JIT=0
DEFINES+=ENABLE_YARR_JIT=0
+ DEFINES+=ENABLE_YARR=0
}
# In debug mode JIT disabled until crash fixed
diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog
index 26dbaf7..1e89d1e 100644
--- a/src/3rdparty/webkit/ChangeLog
+++ b/src/3rdparty/webkit/ChangeLog
@@ -1,3 +1,13 @@
+2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix compilation with win32-icc
+
+ Include os-win32 for stdint.h since MS does not ship that in their PSDK.
+
+ * WebKit.pri:
+
2009-10-30 Adam Barth <abarth@webkit.org>
Reviewed by Mark Rowe.
diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
index 382a8c7..50cff63 100644
--- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog
+++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
@@ -1,3 +1,51 @@
+2009-12-18 Yongjun Zhang <yongjun.zhang@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32713
+ [Qt] make wtf/Assertions.h compile in winscw compiler.
+
+ Add string arg before ellipsis to help winscw compiler resolve variadic
+ macro definitions in wtf/Assertions.h.
+
+ * wtf/Assertions.h:
+
+2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix compilation with win32-icc
+
+ The Intel compiler does not support the __has_trivial_constructor type
+ trait. The Intel Compiler can report itself as _MSC_VER >= 1400. The
+ reason for that is that the Intel Compiler depends on the Microsoft
+ Platform SDK, and in order to try to be "fully" MS compatible it will
+ "pretend" to be the same MS compiler as was shipped with the MS PSDK.
+ (Thus, compiling with win32-icc with VC8 SDK will make the source code
+ "think" the compiler at hand supports this type trait).
+
+ * wtf/TypeTraits.h:
+
+2009-11-28 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ Apply workaround for the limitation of VirtualFree with MEM_RELEASE to all ports running on Windows
+ https://bugs.webkit.org/show_bug.cgi?id=31943
+
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::MarkStackArray::shrinkAllocation):
+
+2009-11-18 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler.
+
+ Fix the clobber list of cacheFlush for ARM and Thumb2 on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=31631
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
2009-11-23 Laszlo Gombos <laszlo.1.gombos@nokia.com>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h
index 5c43eeb..9ca62c8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h
@@ -203,7 +203,7 @@ public:
"pop {r7}\n"
:
: "r" (code), "r" (reinterpret_cast<char*>(code) + size)
- : "r0", "r1");
+ : "r0", "r1", "r2");
}
#elif PLATFORM(SYMBIAN)
static void cacheFlush(void* code, size_t size)
@@ -224,7 +224,7 @@ public:
"pop {r7}\n"
:
: "r" (code), "r" (reinterpret_cast<char*>(code) + size)
- : "r0", "r1");
+ : "r0", "r1", "r2");
}
#else
#error "The cacheFlush support is missing on this platform."
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h
index ea09f54..a114ae0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h
@@ -153,7 +153,7 @@ namespace JSC {
ASSERT(0 == (size % MarkStack::pageSize()));
if (size == m_allocated)
return;
-#if PLATFORM(WIN) || PLATFORM(SYMBIAN)
+#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN)
// We cannot release a part of a region with VirtualFree. To get around this,
// we'll release the entire region and reallocate the size that we want.
releaseStack(m_data, m_allocated);
diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h
index f529a62..aa72e5a 100644
--- a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h
+++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h
@@ -158,8 +158,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#define ASSERT(assertion) ((void)0)
#if COMPILER(MSVC7)
#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define ASSERT_WITH_MESSAGE(assertion...) ((void)0)
+#elif COMPILER(WINSCW)
+#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
#else
#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
#endif /* COMPILER(MSVC7) */
@@ -176,8 +176,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
while (0)
#if COMPILER(MSVC7)
#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define ASSERT_WITH_MESSAGE(assertion...) ((void)0)
+#elif COMPILER(WINSCW)
+#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
#else
#define ASSERT_WITH_MESSAGE(assertion, ...) do \
if (!(assertion)) { \
@@ -219,11 +219,11 @@ while (0)
/* FATAL */
-#if FATAL_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
+#if FATAL_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW)
#define FATAL(...) ((void)0)
#elif COMPILER(MSVC7)
#define FATAL() ((void)0)
-#elif PLATFORM(SYMBIAN)
+#elif COMPILER(WINSCW)
#define FATAL(args...) ((void)0)
#else
#define FATAL(...) do { \
@@ -234,24 +234,24 @@ while (0)
/* LOG_ERROR */
-#if ERROR_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
+#if ERROR_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW)
#define LOG_ERROR(...) ((void)0)
#elif COMPILER(MSVC7)
#define LOG_ERROR() ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG_ERROR(args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG_ERROR(arg...) ((void)0)
#else
#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
#endif
/* LOG */
-#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
+#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW)
#define LOG(channel, ...) ((void)0)
#elif COMPILER(MSVC7)
#define LOG() ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG(channel, args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG(arg...) ((void)0)
#else
#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
@@ -260,12 +260,12 @@ while (0)
/* LOG_VERBOSE */
-#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
+#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW)
#define LOG_VERBOSE(channel, ...) ((void)0)
#elif COMPILER(MSVC7)
#define LOG_VERBOSE(channel) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG_VERBOSE(channel, args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG_VERBOSE(channel, arg...) ((void)0)
#else
#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
#endif
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index 5818e83..daa3be7 100644
--- a/src/3rdparty/webkit/VERSION
+++ b/src/3rdparty/webkit/VERSION
@@ -8,4 +8,4 @@ The commit imported was from the
and has the sha1 checksum
- efa69b6181ce5c045097351cdcf6c158da3f4888
+ 70b5989bdeea2f73bd950099fc0f0e954550ef54
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index 9644470..03bb1fb 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,130 @@
+2009-12-30 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Add support for Symbian def files
+
+ * WebCore.pro:
+
+2009-12-30 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Unreviewed Qt/Symbian build fix.
+
+ Don't build network state notifier support when building inside of Qt.
+ Otherwise the Qt build depends on an external module that itself depends
+ on Qt again.
+
+ * WebCore.pro:
+
+2009-12-30 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Turn off DataGrid support by default.
+
+ No new tests, as there is no new functionality.
+
+ * WebCore.pro:
+
+2009-12-17 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] support navigator.onLine and ononline/onoffline events.
+ https://bugs.webkit.org/show_bug.cgi?id=32555
+
+ Hooked up Bearer Management to NetworkStateNotifier. This solution is available
+ only if QtMobility's Bearer Management is installed.
+
+ * WebCore.pro:
+ * platform/network/NetworkStateNotifier.h:
+ * platform/network/qt/NetworkStateNotifierPrivate.h: Added.
+ * platform/network/qt/NetworkStateNotifierQt.cpp: Added.
+ (WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate):
+ (WebCore::NetworkStateNotifierPrivate::onlineStateChanged):
+ (WebCore::NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate):
+ (WebCore::NetworkStateNotifier::updateState):
+ (WebCore::NetworkStateNotifier::NetworkStateNotifier):
+
+2009-12-17 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Symbian build fix: Don't include QtXml/qxmlstream.h but omit the prefix, to
+ make sure we pick up the header file from QtCore. That is where the implementation
+ is compiled.
+
+ * dom/XMLTokenizer.h:
+
+2009-12-14 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Add manual test for JavaScript prompt corner case
+ https://bugs.webkit.org/show_bug.cgi?id=30914
+
+ The patch is based on the work done by Gupta Manish.
+
+ Verify behavior of the JavaScript prompt function. Currently
+ Qt is not behaving like other WebKit ports and Firefox in
+ regards to accepting the prompt but not entering a text.
+
+ * manual-tests/qt/java-script-prompt.html: Added.
+
+2009-12-21 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Fix assertion failure when dragging an SVG image.
+ https://bugs.webkit.org/show_bug.cgi?id=32511
+
+ Test: fast/images/drag-svg-as-image.html
+
+ * svg/graphics/SVGImage.cpp:
+ (WebCore::SVGImage::filenameExtension): Return "svg"
+ * svg/graphics/SVGImage.h:
+
+2009-11-23 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Wrong runtime instance objects of wrapped QObjects may be used if
+ the wrapped object died before the gc removed the instance.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31681
+
+ Before using a cached instance, verify that its wrapped QObject is
+ still alive.
+
+ * bridge/qt/qt_instance.cpp:
+ (JSC::Bindings::QtInstance::getQtInstance):
+ * bridge/qt/qt_instance.h:
+ (JSC::Bindings::QtInstance::hashKey):
+
+2009-11-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix crash of QtWebKit on any page with Flash when compiled with MinGW.
+
+ Fix inline assembly, don't dereference the function pointer twice.
+
+ * plugins/win/PluginViewWin.cpp:
+ (WebCore::PluginView::hookedBeginPaint):
+ (WebCore::PluginView::hookedEndPaint):
+
+2009-11-22 Jakub Wieczorek <faw217@gmail.com>
+
+ Reviewed by Adam Barth.
+
+ [Qt] Remove the Referer header when redirecting to a non-secure site
+ https://bugs.webkit.org/show_bug.cgi?id=31785
+
+ This makes Qt pass two tests introduced in r50226.
+
+ * platform/network/qt/QNetworkReplyHandler.cpp:
+ (WebCore::QNetworkReplyHandler::sendResponseIfNeeded):
+
2009-11-19 Olivier Goffart <ogoffart@trolltech.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro
index 9239089..be64e3b 100644
--- a/src/3rdparty/webkit/WebCore/WebCore.pro
+++ b/src/3rdparty/webkit/WebCore/WebCore.pro
@@ -136,7 +136,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) {
!contains(DEFINES, ENABLE_SHARED_WORKERS=.): DEFINES += ENABLE_SHARED_WORKERS=1
!contains(DEFINES, ENABLE_WORKERS=.): DEFINES += ENABLE_WORKERS=1
!contains(DEFINES, ENABLE_XHTMLMP=.): DEFINES += ENABLE_XHTMLMP=0
-!contains(DEFINES, ENABLE_DATAGRID=.): DEFINES += ENABLE_DATAGRID=1
+!contains(DEFINES, ENABLE_DATAGRID=.): DEFINES += ENABLE_DATAGRID=0
# SVG support
!contains(DEFINES, ENABLE_SVG=0) {
@@ -180,6 +180,15 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) {
else:DEFINES += ENABLE_XSLT=0
}
+!CONFIG(QTDIR_build):!contains(DEFINES, ENABLE_QT_BEARER=.) {
+ symbian: {
+ exists($${EPOCROOT}epoc32/release/winscw/udeb/QtBearer.lib)| \
+ exists($${EPOCROOT}epoc32/release/armv5/lib/QtBearer.lib) {
+ DEFINES += ENABLE_QT_BEARER=1
+ }
+ }
+}
+
DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1
# Used to compute defaults for the build-webkit script
@@ -2860,6 +2869,17 @@ contains(DEFINES, ENABLE_XHTMLMP=1) {
FEATURE_DEFINES_JAVASCRIPT += ENABLE_XHTMLMP=1
}
+contains(DEFINES, ENABLE_QT_BEARER=1) {
+ HEADERS += \
+ platform/network/qt/NetworkStateNotifierPrivate.h
+
+ SOURCES += \
+ platform/network/qt/NetworkStateNotifierQt.cpp
+
+ LIBS += -lQtBearer
+
+}
+
contains(DEFINES, ENABLE_SVG=1) {
FEATURE_DEFINES_JAVASCRIPT += ENABLE_SVG=1
@@ -3382,16 +3402,15 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4
}
}
-# Temporary workaround to pick up the DEF file from the same place as all the others
symbian {
shared {
contains(MMP_RULES, defBlock) {
MMP_RULES -= defBlock
MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \
- "DEFFILE ../../../s60installs/bwins/$${TARGET}.def" \
+ "DEFFILE ../WebKit/qt/symbian/bwins/$${TARGET}.def" \
"$${LITERAL_HASH}elif defined EABI" \
- "DEFFILE ../../../s60installs/eabi/$${TARGET}.def" \
+ "DEFFILE ../WebKit/qt/symbian/eabi/$${TARGET}.def" \
"$${LITERAL_HASH}endif"
}
}
diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp
index 0546014..ec362ec 100644
--- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp
+++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp
@@ -111,10 +111,17 @@ PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObje
{
JSLock lock(SilenceAssertionsOnly);
- foreach(QtInstance* instance, cachedInstances.values(o)) {
- if (instance->rootObject() == rootObject)
- return instance;
- }
+ foreach(QtInstance* instance, cachedInstances.values(o))
+ if (instance->rootObject() == rootObject) {
+ // The garbage collector removes instances, but it may happen that the wrapped
+ // QObject dies before the gc kicks in. To handle that case we have to do an additional
+ // check if to see if the instance's wrapped object is still alive. If it isn't, then
+ // we have to create a new wrapper.
+ if (!instance->getObject())
+ cachedInstances.remove(instance->hashKey());
+ else
+ return instance;
+ }
RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership);
cachedInstances.insert(o, ret.get());
diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h
index 00aaa5b..0afc6c7 100644
--- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h
+++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h
@@ -59,6 +59,7 @@ public:
JSValue booleanValue() const;
QObject* getObject() const { return m_object; }
+ QObject* hashKey() const { return m_hashkey; }
static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership);
diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
index e1ee09f..a83e73a 100644
--- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
+++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h
@@ -34,7 +34,7 @@
#include <wtf/OwnPtr.h>
#if USE(QXMLSTREAM)
-#include <QtXml/qxmlstream.h>
+#include <qxmlstream.h>
#else
#include <libxml/tree.h>
#include <libxml/xmlstring.h>
diff --git a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h
index 0189f5f..f8c5654 100644
--- a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h
+++ b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h
@@ -46,6 +46,10 @@ typedef const struct __SCDynamicStore * SCDynamicStoreRef;
namespace WebCore {
+#if (PLATFORM(QT) && ENABLE(QT_BEARER))
+class NetworkStateNotifierPrivate;
+#endif
+
class NetworkStateNotifier {
public:
NetworkStateNotifier();
@@ -78,10 +82,14 @@ private:
#elif PLATFORM(CHROMIUM)
NetworkStateNotifierPrivate p;
+
+#elif PLATFORM(QT) && ENABLE(QT_BEARER)
+ friend class NetworkStateNotifierPrivate;
+ NetworkStateNotifierPrivate* p;
#endif
};
-#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM)
+#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) && !(PLATFORM(QT) && ENABLE(QT_BEARER))
inline NetworkStateNotifier::NetworkStateNotifier()
: m_isOnLine(true)
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h
new file mode 100644
index 0000000..7af6392
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef NetworkStateNotifierPrivate_h
+#define NetworkStateNotifierPrivate_h
+
+#include <QObject>
+
+namespace QtMobility {
+class QNetworkConfigurationManager;
+}
+
+namespace WebCore {
+
+class NetworkStateNotifier;
+
+class NetworkStateNotifierPrivate : public QObject {
+ Q_OBJECT
+public:
+ NetworkStateNotifierPrivate(NetworkStateNotifier* notifier);
+ ~NetworkStateNotifierPrivate();
+public slots:
+ void onlineStateChanged(bool);
+
+public:
+ QtMobility::QNetworkConfigurationManager* m_configurationManager;
+ bool m_online;
+ NetworkStateNotifier* m_notifier;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
new file mode 100644
index 0000000..f74398b
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "NetworkStateNotifier.h"
+
+#include "NetworkStateNotifierPrivate.h"
+#include "qnetworkconfigmanager.h"
+
+using namespace QtMobility;
+
+namespace WebCore {
+
+NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier)
+ : m_configurationManager(new QNetworkConfigurationManager())
+ , m_online(m_configurationManager->isOnline())
+ , m_notifier(notifier)
+{
+ Q_ASSERT(notifier);
+ connect(m_configurationManager, SIGNAL(onlineStateChanged(bool)), this, SLOT(onlineStateChanged(bool)));
+}
+
+void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline)
+{
+ if (m_online == isOnline)
+ return;
+
+ m_online = isOnline;
+ m_notifier->updateState();
+}
+
+NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate()
+{
+ delete m_configurationManager;
+}
+
+void NetworkStateNotifier::updateState()
+{
+ if (m_isOnLine == p->m_online)
+ return;
+
+ m_isOnLine = p->m_online;
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(true)
+ , m_networkStateChangedFunction(0)
+{
+ p = new NetworkStateNotifierPrivate(this);
+ m_isOnLine = p->m_online;
+}
+
+} // namespace WebCore
+
+#include "moc_NetworkStateNotifierPrivate.cpp"
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 2f4722f..1ac80f6 100644
--- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -325,6 +325,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
newRequest.setHTTPMethod("GET");
}
+ // Should not set Referer after a redirect from a secure resource to non-secure one.
+ if (!newRequest.url().protocolIs("https") && protocolIs(newRequest.httpReferrer(), "https"))
+ newRequest.clearHTTPReferrer();
+
client->willSendRequest(m_resourceHandle, newRequest, response);
m_redirected = true;
m_request = newRequest.toNetworkRequest(m_resourceHandle->getInternal()->m_frame);
diff --git a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp
index 0a506f8..b74e912 100644
--- a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp
+++ b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.cpp
@@ -267,6 +267,11 @@ bool SVGImage::dataChanged(bool allDataReceived)
return m_page;
}
+String SVGImage::filenameExtension() const
+{
+ return "svg";
+}
+
}
#endif // ENABLE(SVG)
diff --git a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h
index 2cea91a..0f05429 100644
--- a/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h
+++ b/src/3rdparty/webkit/WebCore/svg/graphics/SVGImage.h
@@ -47,6 +47,8 @@ namespace WebCore {
private:
virtual ~SVGImage();
+ virtual String filenameExtension() const;
+
virtual void setContainerSize(const IntSize&);
virtual bool usesContainerSize() const;
virtual bool hasRelativeWidth() const;
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp
index 8922150..441bec7 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp
@@ -99,6 +99,14 @@ public:
It is possible to replace the contents of child elements using
setPlainText() and setInnerXml(). To replace the element itself and its
contents, use setOuterXml().
+
+ \section1 Examples
+
+ The \l{DOM Traversal Example} shows one way to traverse documents in a running
+ example.
+
+ The \l{Simple Selector Example} can be used to experiment with the searching
+ features of this class and provides sample code you can start working with.
*/
/*!
@@ -195,8 +203,7 @@ bool QWebElement::isNull() const
\a selectorQuery. If there are no matching elements, an empty list is
returned.
- \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector}
- syntax is used for the query.
+ \l{Standard CSS2 selector} syntax is used for the query.
\note This search is performed recursively.
@@ -211,8 +218,7 @@ QWebElementCollection QWebElement::findAll(const QString &selectorQuery) const
Returns the first child element that matches the given CSS selector
\a selectorQuery.
- \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector}
- syntax is used for the query.
+ \l{Standard CSS2 selector} syntax is used for the query.
\note This search is performed recursively.
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp
index f43cbbf..1145744 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebinspector.cpp
@@ -139,6 +139,9 @@ QSize QWebInspector::sizeHint() const
/*! \reimp */
bool QWebInspector::event(QEvent* ev)
{
+ if (ev->type() == QEvent::Close && d->page)
+ d->page->d->inspectorController()->setWindowVisible(false);
+
return QWidget::event(ev);
}
@@ -159,8 +162,6 @@ void QWebInspector::showEvent(QShowEvent* event)
/*! \reimp */
void QWebInspector::hideEvent(QHideEvent* event)
{
- if (d->page)
- d->page->d->inspectorController()->setWindowVisible(false);
}
/*! \internal */
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index aedf95a..6d08c32 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -864,7 +864,12 @@ void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button)
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ Frame* frame = page->focusController()->focusedFrame();
+ if (!frame)
+ return;
+
if (client && client->inputMethodEnabled()
+ && frame->document()->focusedNode()
&& button == Qt::LeftButton && qApp->autoSipEnabled()) {
QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
@@ -1844,7 +1849,8 @@ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
If the prompt was cancelled by the user the implementation should return false; otherwise the
- result should be written to \a result and true should be returned.
+ result should be written to \a result and true should be returned. If the prompt was not cancelled by the
+ user, the implementation should return true and the result string must not be null.
The default implementation uses QInputDialog::getText.
*/
@@ -3075,7 +3081,7 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const
Q_UNUSED(url)
QString ua = QLatin1String("Mozilla/5.0 ("
- // Plastform
+ // Platform
#ifdef Q_WS_MAC
"Macintosh"
#elif defined Q_WS_QWS
@@ -3084,19 +3090,22 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const
"Windows"
#elif defined Q_WS_X11
"X11"
+#elif defined Q_OS_SYMBIAN
+ "SymbianOS"
#else
"Unknown"
#endif
- "; "
+ // Placeholder for Platform Version
+ "%1; "
// Placeholder for security strength (N or U)
- "%1; "
+ "%2; "
// Subplatform"
#ifdef Q_OS_AIX
"AIX"
#elif defined Q_OS_WIN32
- "%2"
+ "%3"
#elif defined Q_OS_DARWIN
#ifdef __i386__ || __x86_64__
"Intel Mac OS X"
@@ -3148,6 +3157,8 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const
"Sun Solaris"
#elif defined Q_OS_ULTRIX
"DEC Ultrix"
+#elif defined Q_WS_S60
+ "Series60"
#elif defined Q_OS_UNIX
"UNIX BSD/SYSV system"
#elif defined Q_OS_UNIXWARE
@@ -3155,7 +3166,28 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const
#else
"Unknown"
#endif
- "; ");
+ // Placeholder for SubPlatform Version
+ "%4; ");
+
+ // Platform Version
+ QString osVer;
+#ifdef Q_OS_SYMBIAN
+ QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
+ switch (symbianVersion) {
+ case QSysInfo::SV_9_2:
+ osVer = "/9.2";
+ break;
+ case QSysInfo::SV_9_3:
+ osVer = "/9.3";
+ break;
+ case QSysInfo::SV_9_4:
+ osVer = "/9.4";
+ break;
+ default:
+ osVer = "Unknown";
+ }
+#endif
+ ua = ua.arg(osVer);
QChar securityStrength(QLatin1Char('N'));
#if !defined(QT_NO_OPENSSL)
@@ -3219,6 +3251,26 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const
ua = QString(ua).arg(ver);
#endif
+ // SubPlatform Version
+ QString subPlatformVer;
+#ifdef Q_OS_SYMBIAN
+ QSysInfo::S60Version s60Version = QSysInfo::s60Version();
+ switch (s60Version) {
+ case QSysInfo::SV_S60_3_1:
+ subPlatformVer = "/3.1";
+ break;
+ case QSysInfo::SV_S60_3_2:
+ subPlatformVer = "/3.2";
+ break;
+ case QSysInfo::SV_S60_5_0:
+ subPlatformVer = "/5.0";
+ break;
+ default:
+ subPlatformVer = " Unknown";
+ }
+#endif
+ ua = ua.arg(subPlatformVer);
+
// Language
QLocale locale;
if (view())
@@ -3402,9 +3454,9 @@ quint64 QWebPage::bytesReceived() const
/*!
\fn void QWebPage::unsupportedContent(QNetworkReply *reply)
- This signals is emitted when webkit cannot handle a link the user navigated to.
+ This signal is emitted when WebKit cannot handle a link the user navigated to.
- At signal emissions time the meta data of the QNetworkReply \a reply is available.
+ At signal emission time the meta-data of the QNetworkReply \a reply is available.
\note This signal is only emitted if the forwardUnsupportedContent property is set to true.
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h
index e9c1ec8..0f79c70 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h
@@ -51,12 +51,7 @@ class QWEBKIT_EXPORT QWebView : public QWidget {
Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false)
Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor)
-// FIXME: temporary work around for elftran issue that it couldn't find the QPainter::staticMetaObject
-// symbol from Qt lib; it should be reverted after the right symbol is exported.
-// See bug: http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=258893
-#if defined(Q_QDOC) || !defined(Q_OS_SYMBIAN)
Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints)
-#endif
Q_FLAGS(QPainter::RenderHints)
public:
explicit QWebView(QWidget* parent = 0);
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 2408dd4..4ab5bfb 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,133 @@
+2009-12-30 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Upstream Symbian def files from Qt 4.6.
+
+ These files define the ABI of QtWebKit on Symbian.
+
+ * symbian/bwins/QtWebKitu.def: Added.
+ * symbian/eabi/QtWebKitu.def: Added.
+
+2009-12-14 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Fix JavaScript prompt behavior for empty/null strings.
+ https://bugs.webkit.org/show_bug.cgi?id=30914
+
+ The patch is based on the work done by Gupta Manish.
+
+ In the default implementation of the JavaScript prompt
+ we are using a QInputDialog to get the text and this has
+ one quirk with regard to not entering any text.
+
+ In other WebKit ports and in Firefox an empty string is
+ returned but in the Qt case it is a null string.
+
+ Change the API documentation in QWebPage to mention we want to
+ have a non null string but do the fixup in the ChromeClientQt
+ to support existing code.
+
+ * Api/qwebpage.cpp:
+ (QWebPage::javaScriptPrompt): Change API documentation
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::runJavaScriptPrompt): Fixup null QString
+
+2009-12-21 David Boddie <dboddie@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Doc: Minor fixes to language.
+
+ * Api/qwebpage.cpp:
+
+2009-12-15 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by NOBODY (OOPS!).
+
+ [Qt] Do not disable the inspector on show and hide
+ https://bugs.webkit.org/show_bug.cgi?id=31851
+
+ On Qt/X11 with some window managers the window will be
+ hidden when switching windows. In this case all the results
+ are gone when coming back to the window.
+
+ Attempt to use the CloseEvent to figure out if the window
+ was closed and withdrawn as this is more friendly to the
+ user of the inspector client.
+
+ * Api/qwebinspector.cpp:
+ (QWebInspector::event):
+ (QWebInspector::hideEvent):
+
+2009-12-13 Simon Hausmann <hausmann@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ [Qt] Re-enable QWebView::renderHints property for Qt for Symbian
+
+ https://bugs.webkit.org/show_bug.cgi?id=28273
+
+ The bug in Qt's moc that triggered a linking error when declaring this
+ property has been fixed and we can remove the workaround.
+
+ * Api/qwebview.h:
+
+2009-11-30 Abhinav Mithal <abhinav.mithal@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt][Symbian] Report SymbianOS in user agent string for Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=31961
+
+ * Api/qwebpage.cpp:
+ (QWebPage::userAgentForUrl):
+
+2009-11-28 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] SoftwareInputPanelRequest event sent when clicking in newly loaded page
+
+ https://bugs.webkit.org/show_bug.cgi?id=31401
+
+ Don't set the event unless there is a focused node we can use
+ for editing afterwards.
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::handleSoftwareInputPanel):
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::inputMethods):
+
+2009-11-23 David Boddie <dboddie@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Updated the QWebElement documentation with links to examples and
+ external resources.
+ Fixed the project file for the webelement snippet and tidied up the
+ markers used for quoting the code.
+
+ * Api/qwebelement.cpp:
+ * docs/webkitsnippets/webelement/main.cpp:
+ (findAll):
+ * docs/webkitsnippets/webelement/webelement.pro:
+
+2009-11-23 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Wrong runtime instance objects of wrapped QObjects may be used if
+ the wrapped object died before the gc removed the instance.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31681
+
+ Added a unit-test to verify that wrapping a QObject with the
+ same identity as a previously but now dead object works.
+
+ * tests/qwebframe/tst_qwebframe.cpp:
+
2009-11-19 Olivier Goffart <ogoffart@trolltech.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
index 26cf6f6..c5d2792 100644
--- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
@@ -278,7 +278,14 @@ bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const
QString x = result;
FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client());
bool rc = m_webPage->javaScriptPrompt(fl->webFrame(), (QString)message, (QString)defaultValue, &x);
- result = x;
+
+ // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
+ // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
+ if (rc && result.isNull())
+ result = String("");
+ else
+ result = x;
+
return rc;
}
diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp
index d437a6f..2707ffb 100644
--- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp
@@ -22,7 +22,6 @@
#include <qwebview.h>
#include <qwebframe.h>
#include <qwebelement.h>
-#include <qdebug.h>
static QWebFrame *frame;
@@ -53,9 +52,10 @@ static void findAll()
</p>
*/
+//! [FindAll intro]
QList<QWebElement> allSpans = document.findAll("span");
QList<QWebElement> introSpans = document.findAll("p.intro span");
-//! [FindAll]
+//! [FindAll intro] //! [FindAll]
}
int main(int argc, char *argv[])
diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro
index f9b403b..8ca4b59 100644
--- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro
+++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro
@@ -1,5 +1,8 @@
TEMPLATE = app
CONFIG -= app_bundle
+CONFIG(QTDIR_build) {
+ QT += webkit
+}
SOURCES = main.cpp
include(../../../../../WebKit.pri)
QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
diff --git a/src/s60installs/bwins/QtWebKitu.def b/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def
index e5631f8..e5631f8 100644
--- a/src/s60installs/bwins/QtWebKitu.def
+++ b/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def
diff --git a/src/s60installs/eabi/QtWebKitu.def b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def
index 4aad884..4aad884 100644
--- a/src/s60installs/eabi/QtWebKitu.def
+++ b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def
diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
index d88d905..8cc7953 100644
--- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
@@ -605,6 +605,7 @@ private slots:
void render();
void scrollPosition();
void evaluateWillCauseRepaint();
+ void qObjectWrapperWithSameIdentity();
private:
QString evalJS(const QString&s) {
@@ -2785,6 +2786,43 @@ void tst_QWebFrame::evaluateWillCauseRepaint()
QTest::qWait(2000);
}
+class TestFactory : public QObject
+{
+ Q_OBJECT
+public:
+ TestFactory()
+ : obj(0), counter(0)
+ {}
+
+ Q_INVOKABLE QObject* getNewObject()
+ {
+ delete obj;
+ obj = new QObject(this);
+ obj->setObjectName(QLatin1String("test") + QString::number(++counter));
+ return obj;
+
+ }
+
+ QObject* obj;
+ int counter;
+};
+
+void tst_QWebFrame::qObjectWrapperWithSameIdentity()
+{
+ m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>"
+ "<body><span id='span1'>test</span></body>");
+
+ QWebFrame* mainFrame = m_view->page()->mainFrame();
+ QCOMPARE(mainFrame->toPlainText(), QString("test"));
+
+ mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership);
+
+ mainFrame->evaluateJavaScript("triggerBug();");
+ QCOMPARE(mainFrame->toPlainText(), QString("test1"));
+
+ mainFrame->evaluateJavaScript("triggerBug();");
+ QCOMPARE(mainFrame->toPlainText(), QString("test2"));
+}
QTEST_MAIN(tst_QWebFrame)
#include "tst_qwebframe.moc"
diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
index 32002e7..ee1969d 100644
--- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -1487,6 +1487,21 @@ void tst_QWebPage::inputMethods()
QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText));
#endif
+ page->mainFrame()->setHtml("<html><body><p>nothing to input here");
+ viewEventSpy.clear();
+
+ QWebElement para = page->mainFrame()->findFirstElement("p");
+ {
+ QMouseEvent evpres(QEvent::MouseButtonPress, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ page->event(&evpres);
+ QMouseEvent evrel(QEvent::MouseButtonRelease, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ page->event(&evrel);
+ }
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel));
+#endif
+
delete container;
}
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index 3795f56..ed7ac29 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -909,7 +909,7 @@ QAxMetaObject *QAxBase::internalMetaObject() const
\property QAxBase::control
\brief the name of the COM object wrapped by this QAxBase object.
- Setting this property initilializes the COM object. Any COM object
+ Setting this property initializes the COM object. Any COM object
previously set is shut down.
The most efficient way to set this property is by using the
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index d529f67..bc0d35e 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -373,6 +373,13 @@ QVariantAnimation::~QVariantAnimation()
Another example is QEasingCurve::InOutElastic, which provides an
elastic effect on the values of the interpolated variant.
+ QVariantAnimation will use the QEasingCurve::valueForProgress() to
+ transform the "normalized progress" (currentTime / totalDuration)
+ of the animation into the effective progress actually
+ used by the animation. It is this effective progress that will be
+ the progress when interpolated() is called. Also, the steps in the
+ keyValues are referring to this effective progress.
+
The easing curve is used with the interpolator, the interpolated()
virtual function, the animation's duration, and iterationCount, to
control how the current value changes as the animation progresses.
diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp
index 8c4cc82..0fb78d5 100644
--- a/src/corelib/codecs/qiconvcodec.cpp
+++ b/src/corelib/codecs/qiconvcodec.cpp
@@ -378,7 +378,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
}
int invalidCount = 0;
- do {
+ while (inBytesLeft != 0) {
if (iconv(state->cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) {
if (errno == EINVAL && convState) {
// buffer ends in a surrogate
@@ -418,7 +418,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
}
}
}
- } while (inBytesLeft != 0);
+ }
// reset to initial state
iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index f831700..6170272 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -161,7 +161,7 @@ public:
QByteArray fromUnicode(const QString& str);
QByteArray fromUnicode(const QChar *uc, int len);
#ifdef QT3_SUPPORT
- QByteArray fromUnicode(const QString& uc, int& lenInOut);
+ QT3_SUPPORT QByteArray fromUnicode(const QString& uc, int& lenInOut);
#endif
bool hasFailure() const;
private:
diff --git a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp
index 15b8ecd..e93394f 100644
--- a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp
+++ b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp
@@ -46,6 +46,9 @@
#include <mach/mach_time.h>
#include <unistd.h>
#elif defined(Q_OS_UNIX)
+#if defined(Q_OS_HURD)
+#include <sys/time.h>
+#endif
#include <time.h>
#include <unistd.h>
#elif defined(Q_OS_WIN)
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 62b5409..0c94482 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -77,6 +77,7 @@
#include <e32def.h>
#include <e32debug.h>
#include <f32file.h>
+#include <e32math.h>
# include "private/qcore_symbian_p.h"
_LIT(qt_S60Filter, "Series60v?.*.sis");
@@ -2493,7 +2494,7 @@ bool qputenv(const char *varName, const QByteArray& value)
#endif
}
-#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
+#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
# if defined(Q_OS_INTEGRITY) && defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 500)
// older versions of INTEGRITY used a long instead of a uint for the seed.
@@ -2516,8 +2517,6 @@ Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
Sets the argument \a seed to be used to generate a new random number sequence of
pseudo random integers to be returned by qrand().
- If no seed value is provided, qrand() is automatically seeded with a value of 1.
-
The sequence of random numbers generated is deterministic per thread. For example,
if two threads call qsrand(1) and subsequently calls qrand(), the threads will get
the same random number sequence.
@@ -2541,8 +2540,9 @@ void qsrand(uint seed)
srand(seed);
}
#else
- // On Windows srand() and rand() already use Thread-Local-Storage
+ // On Windows and Symbian srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
+ // this is also valid for QT_NO_THREAD
srand(seed);
#endif
}
@@ -2558,7 +2558,7 @@ void qsrand(uint seed)
*/
void qsrand()
{
-#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
+#if (defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
SeedStorage *seedStorage = randTLS();
if (seedStorage) {
SeedStorageType *pseed = seedStorage->localData();
@@ -2572,24 +2572,28 @@ void qsrand()
*pseed = QDateTime::currentDateTime().toTime_t()
+ quintptr(&pseed)
+ serial.fetchAndAddRelaxed(1);
-#if defined(Q_OS_WIN)
- // for Windows the srand function must still be called.
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ // for Windows and Symbian the srand function must still be called.
srand(*pseed);
#endif
}
-#elif defined(Q_OS_WIN)
+//QT_NO_THREAD implementations
+#else
static unsigned int seed = 0;
if (seed)
return;
+#if defined(Q_OS_SYMBIAN)
+ seed = Math::Random();
+#elif defined(Q_OS_WIN)
seed = GetTickCount();
- srand(seed);
#else
- // Symbian?
-
-#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
+ seed = quintptr(&seed) + QDateTime::currentDateTime().toTime_t();
+#endif
+ srand(seed);
+#endif // defined(Q_OS_UNIX) || defined(Q_OS_WIN)) && !defined(QT_NO_THREAD)
}
/*!
@@ -2626,8 +2630,9 @@ int qrand()
return rand();
}
#else
- // On Windows srand() and rand() already use Thread-Local-Storage
+ // On Windows and Symbian srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
+ // this is also valid for QT_NO_THREAD
return rand();
#endif
}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 2e9f839..6623e0c 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.6.0"
+#define QT_VERSION_STR "4.6.1"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x040600
+#define QT_VERSION 0x040601
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index ff8c6c8..c1c7812 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -93,7 +93,7 @@ public:
inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); }
- inline QDebug &operator<<(QBool t) { stream->ts << (bool(t) ? "true" : "false"); return maybeSpace(); }
+ inline QDebug &operator<<(QBool t) { stream->ts << (bool(t != 0) ? "true" : "false"); return maybeSpace(); }
inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 61081a1..0a435b9 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -573,6 +573,8 @@ QString QFileInfo::canonicalFilePath() const
QString QFileInfo::absolutePath() const
{
Q_D(const QFileInfo);
+ if (d->data->fileName.isEmpty())
+ qWarning("QFileInfo::absolutePath: Constructed with empty filename");
if(!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::AbsolutePathName);
diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp
index 17ac9c6..c70232c 100644
--- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp
@@ -269,8 +269,11 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
}
}
- fd = ::dirfd(d);
- int parentFd = parent?::dirfd(parent):0;
+ fd = qt_safe_dup(::dirfd(d));
+ int parentFd = parent ? qt_safe_dup(::dirfd(parent)) : 0;
+
+ ::closedir(d);
+ if(parent) ::closedir(parent);
Q_ASSERT(fd);
if(::fcntl(fd, F_SETSIG, SIGIO) ||
@@ -279,10 +282,6 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
(parent && ::fcntl(parentFd, F_SETSIG, SIGIO)) ||
(parent && ::fcntl(parentFd, F_NOTIFY, DN_DELETE | DN_RENAME |
DN_MULTISHOT))) {
-
- ::closedir(d);
- if(parent) ::closedir(parent);
-
continue; // Could not set appropriate flags
}
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 3cf9b7e..e4c4e3f 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -55,6 +55,7 @@
#include "private/qcore_unix_p.h"
#endif
#include <stdio.h>
+#include <stdlib.h>
QT_BEGIN_NAMESPACE
@@ -137,6 +138,21 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path)
if (path.isEmpty())
return path;
+ // FIXME let's see if this stuff works, then we might be able to remove some of the other code.
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ if (path.size() == 1 && path.at(0) == QLatin1Char('/'))
+ return path;
+#endif
+ // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here.
+#if defined(Q_OS_LINIX) || defined(Q_OS_SYMBIAN)
+ char *ret = realpath(path.toLocal8Bit().constData(), (char*)0);
+ if (ret) {
+ QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret));
+ free(ret);
+ return canonicalPath;
+ }
+#endif
+
QFileInfo fi;
const QChar slash(QLatin1Char('/'));
QString tmpPath = path;
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 87f0737..41a6a1b 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
#define Q_USE_DEPRECATED_MAP_API 1
#endif
-class QFSFileEnginePrivate : public QAbstractFileEnginePrivate
+class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
{
Q_DECLARE_PUBLIC(QFSFileEngine)
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 8cbf6a3..ea262bf 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -191,12 +191,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
return false;
}
- QT_STATBUF statBuf;
- if (QT_FSTAT(fd, &statBuf) != -1) {
- if ((statBuf.st_mode & S_IFMT) == S_IFDIR) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
- QT_CLOSE(fd);
- return false;
+ if (!(openMode & QIODevice::WriteOnly)) {
+ // we don't need this check if we tried to open for writing because then
+ // we had received EISDIR anyway.
+ QT_STATBUF statBuf;
+ if (QT_FSTAT(fd, &statBuf) != -1) {
+ if ((statBuf.st_mode & S_IFMT) == S_IFDIR) {
+ q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ QT_CLOSE(fd);
+ return false;
+ }
}
}
@@ -230,12 +234,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
return false;
}
- QT_STATBUF statBuf;
- if (QT_FSTAT(fileno(fh), &statBuf) != -1) {
- if ((statBuf.st_mode & S_IFMT) == S_IFDIR) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
- fclose(fh);
- return false;
+ if (!(openMode & QIODevice::WriteOnly)) {
+ // we don't need this check if we tried to open for writing because then
+ // we had received EISDIR anyway.
+ QT_STATBUF statBuf;
+ if (QT_FSTAT(fileno(fh), &statBuf) != -1) {
+ if ((statBuf.st_mode & S_IFMT) == S_IFDIR) {
+ q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ fclose(fh);
+ return false;
+ }
}
}
@@ -817,10 +825,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
ret |= RootFlag;
} else {
QString baseName = fileName(BaseName);
- if ((baseName.size() > 1
- && baseName.at(0) == QLatin1Char('.') && baseName.at(1) != QLatin1Char('.'))
+ if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.'))
# if !defined(QWS) && defined(Q_OS_MAC)
- || _q_isMacHidden(d->filePath)
+ || _q_isMacHidden(d->filePath)
# endif
) {
ret |= HiddenFlag;
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index a6cb5a9..a7719a8 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1595,13 +1595,10 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
ret |= LocalDiskFlag;
if (d->doStat()) {
ret |= ExistsFlag;
- if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) {
+ if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath))
ret |= RootFlag;
- } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) {
- QString baseName = fileName(BaseName);
- if (baseName != QLatin1String(".") && baseName != QLatin1String(".."))
- ret |= HiddenFlag;
- }
+ else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN)
+ ret |= HiddenFlag;
}
}
return ret;
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 37161bc..c78af3c 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -275,7 +275,7 @@ QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &o
*/
bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
{
- return d->hash == other.d->hash;
+ return d == other.d || (d && other.d && d->hash == other.d->hash);
}
/*!
@@ -334,6 +334,7 @@ bool QProcessEnvironment::contains(const QString &name) const
*/
void QProcessEnvironment::insert(const QString &name, const QString &value)
{
+ // d detaches from null
d->hash.insert(prepareName(name), prepareValue(value));
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 5c543d4..a061ad1 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -273,7 +273,7 @@ QResourcePrivate::load(const QString &file)
QString cleaned = cleanPath(file);
for(int i = 0; i < list->size(); ++i) {
QResourceRoot *res = list->at(i);
- const int node = res->findNode(cleaned);
+ const int node = res->findNode(cleaned, locale);
if(node != -1) {
if(related.isEmpty()) {
container = res->isContainer(node);
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 594718e..47f340c 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -440,7 +440,7 @@ QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
readConverterSavedState(0),
#endif
readConverterSavedStateOffset(0),
- locale(QLocale::C)
+ locale(QLocale::c())
{
this->q_ptr = q_ptr;
reset();
@@ -1806,8 +1806,7 @@ QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong
if (ch.isDigit()) {
val *= 10;
val += ch.digitValue();
- } else if (locale.language() != QLocale::C
- && ch == locale.groupSeparator()) {
+ } else if (locale != QLocale::c() && ch == locale.groupSeparator()) {
continue;
} else {
ungetChar(ch);
@@ -1958,7 +1957,7 @@ bool QTextStreamPrivate::getReal(double *f)
else if (lc == locale.negativeSign().toLower()
|| lc == locale.positiveSign().toLower())
input = InputSign;
- else if (locale.language() != QLocale::C // backward-compatibility
+ else if (locale != QLocale::c() // backward-compatibility
&& lc == locale.groupSeparator().toLower())
input = InputDigit; // well, it isn't a digit, but no one cares.
else
@@ -2283,7 +2282,7 @@ bool QTextStreamPrivate::putNumber(qulonglong number, bool negative)
// add thousands group separators. For backward compatibility we
// don't add a group separator for C locale.
- if (locale.language() != QLocale::C)
+ if (locale != QLocale::c())
flags |= QLocalePrivate::ThousandsGroup;
const QLocalePrivate *dd = locale.d();
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index fd51bcf..6ac6468 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -3864,14 +3864,18 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
url += "//";
if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
+ bool hasUserOrPass = false;
if (!userName.isEmpty()) {
url += encodedUserName;
- if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
- url += ':';
- url += encodedPassword;
- }
- url += '@';
+ hasUserOrPass = true;
}
+ if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
+ url += ':';
+ url += encodedPassword;
+ hasUserOrPass = true;
+ }
+ if (hasUserOrPass)
+ url += '@';
}
if (host.startsWith(QLatin1Char('['))) {
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 5885591..d0dc7be 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -129,7 +129,7 @@ static inline bool time_update(struct timeval *tv, const struct timeval &start,
// clock source is monotonic, so we can recalculate how much timeout is left
struct timeval now = qt_gettime();
*tv = timeout + start - now;
- return true;
+ return tv->tv_sec >= 0;
}
int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
@@ -154,7 +154,8 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
// recalculate the timeout
if (!time_update(&timeout, start, *orig_timeout)) {
- // clock reset, fake timeout error
+ // timeout during update
+ // or clock reset, fake timeout error
return 0;
}
}
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 665b73e..16871c3 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -341,6 +341,11 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
g_source_attach(&idleTimerSource->source, mainContext);
}
+void QEventDispatcherGlibPrivate::runTimersOnceWithNormalPriority()
+{
+ timerSource->runWithIdlePriority = false;
+}
+
QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent)
: QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate), parent)
{
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index 6a4e726..57cbf94 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -110,6 +110,8 @@ public:
GSocketNotifierSource *socketNotifierSource;
GTimerSource *timerSource;
GIdleTimerSource *idleTimerSource;
+
+ void runTimersOnceWithNormalPriority();
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index b197b9d..c305341 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -336,6 +336,7 @@ public:
// internal window handle used for socketnotifiers/timers/etc
HWND internalHwnd;
+ HHOOK getMessageHook;
// for controlling when to send posted events
QAtomicInt serialNumber;
@@ -363,7 +364,7 @@ public:
};
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
- : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), serialNumber(0), lastSerialNumber(0), wakeUps(0)
+ : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), wakeUps(0)
{
resolveTimerAPI();
}
@@ -471,37 +472,11 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
}
return 0;
} else if (message == WM_TIMER) {
- if (wp == SendPostedEventsTimerId) {
- KillTimer(d->internalHwnd, wp);
- int localSerialNumber = d->serialNumber;
- (void) d->wakeUps.fetchAndStoreRelease(0);
- if (localSerialNumber != d->lastSerialNumber) {
- PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
- }
- } else {
- Q_ASSERT(d != 0);
- d->sendTimerEvent(wp);
- }
+ Q_ASSERT(d != 0);
+ d->sendTimerEvent(wp);
return 0;
} else if (message == WM_QT_SENDPOSTEDEVENTS) {
int localSerialNumber = d->serialNumber;
-
- if (GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER) != 0) {
- // delay the next pass of sendPostedEvents() until we get the special
- // WM_TIMER, which allows all pending Windows messages to be processed
- if (SetTimer(d->internalHwnd, SendPostedEventsTimerId, 0, 0) == 0) {
- // failed to start the timer, oops, clear wakeUps in an attempt to keep things running
- qErrnoWarning("Qt: INTERNAL ERROR: failed to start sendPostedEvents() timer");
- d->wakeUps.fetchAndStoreRelease(0);
- } else {
- // SetTimer() succeeded, nothing to do now
- ;
- }
- } else {
- // nothing pending in the queue, let sendPostedEvents go through
- d->wakeUps.fetchAndStoreRelease(0);
- }
-
if (localSerialNumber != d->lastSerialNumber) {
d->lastSerialNumber = localSerialNumber;
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
@@ -512,6 +487,35 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
return DefWindowProc(hwnd, message, wp, lp);
}
+LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
+{
+ if (wp == PM_REMOVE) {
+ QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
+ Q_ASSERT(q != 0);
+ if (q) {
+ QEventDispatcherWin32Private *d = q->d_func();
+ int localSerialNumber = d->serialNumber;
+ if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) {
+ // no more input or timer events in the message queue, we can allow posted events to be
+ // sent now
+ (void) d->wakeUps.fetchAndStoreRelease(0);
+ MSG *msg = (MSG *) lp;
+ if (localSerialNumber != d->lastSerialNumber
+ // if this message IS the one that triggers sendPostedEvents(), no need to post it again
+ && msg->hwnd != d->internalHwnd
+ && msg->message != WM_QT_SENDPOSTEDEVENTS) {
+ PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
+ }
+ }
+ }
+ }
+#ifdef Q_OS_WINCE
+ return 0;
+#else
+ return CallNextHookEx(0, code, wp, lp);
+#endif
+}
+
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
{
// make sure that multiple Qt's can coexist in the same process
@@ -636,6 +640,14 @@ void QEventDispatcherWin32::createInternalHwnd()
return;
d->internalHwnd = qt_create_internal_window(this);
+#ifndef Q_OS_WINCE
+ // setup GetMessage hook needed to drive our posted events
+ d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
+ if (!d->getMessageHook) {
+ qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook");
+ }
+#endif
+
// register all socket notifiers
QList<int> sockets = (d->sn_read.keys().toSet()
+ d->sn_write.keys().toSet()
@@ -725,6 +737,11 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
}
if (haveMessage) {
+#ifdef Q_OS_WINCE
+ // WinCE doesn't support hooks at all, so we have to call this by hand :(
+ (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
+#endif
+
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
if (seenWM_QT_SENDPOSTEDEVENTS) {
needWM_QT_SENDPOSTEDEVENTS = true;
@@ -1058,6 +1075,12 @@ void QEventDispatcherWin32::closingDown()
d->unregisterTimer(d->timerVec.at(i), true);
d->timerVec.clear();
d->timerDict.clear();
+
+#ifndef Q_OS_WINCE
+ if (d->getMessageHook)
+ UnhookWindowsHookEx(d->getMessageHook);
+ d->getMessageHook = 0;
+#endif
}
bool QEventDispatcherWin32::event(QEvent *e)
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index a5ef4d4..7f0e87d 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -102,6 +102,7 @@ public:
private:
friend LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
+ friend LRESULT CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM);
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h
index a9e4378..16e6bb7 100644
--- a/src/corelib/kernel/qmath.h
+++ b/src/corelib/kernel/qmath.h
@@ -46,6 +46,10 @@
#include <QtCore/qglobal.h>
+#ifdef Q_OS_SYMBIAN
+# include <e32math.h>
+#endif
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -76,44 +80,142 @@ inline int qFloor(qreal v)
return int(floor(v));
}
-inline qreal qSin(qreal v)
+inline qreal qFabs(qreal v)
{
#ifdef QT_USE_MATH_H_FLOATS
- if (sizeof(qreal) == sizeof(float))
- return sinf(float(v));
+ if(sizeof(qreal) == sizeof(float))
+ return fabsf(float(v));
else
#endif
- return sin(v);
+ return fabs(v);
+}
+
+inline qreal qSin(qreal v)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal sin_v;
+ Math::Sin(sin_v, static_cast<TReal>(v));
+ return static_cast<qreal>(sin_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return sinf(float(v));
+ else
+# endif
+ return sin(v);
+#endif
}
inline qreal qCos(qreal v)
{
-#ifdef QT_USE_MATH_H_FLOATS
- if (sizeof(qreal) == sizeof(float))
- return cosf(float(v));
- else
+#ifdef Q_OS_SYMBIAN
+ TReal cos_v;
+ Math::Cos(cos_v, static_cast<TReal>(v));
+ return static_cast<qreal>(cos_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return cosf(float(v));
+ else
+# endif
+ return cos(v);
+#endif
+}
+
+inline qreal qTan(qreal v)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal tan_v;
+ Math::Tan(tan_v, static_cast<TReal>(v));
+ return static_cast<qreal>(tan_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return tanf(float(v));
+ else
+# endif
+ return tan(v);
#endif
- return cos(v);
}
inline qreal qAcos(qreal v)
{
-#ifdef QT_USE_MATH_H_FLOATS
- if (sizeof(qreal) == sizeof(float))
- return acosf(float(v));
- else
+#ifdef Q_OS_SYMBIAN
+ TReal acos_v;
+ Math::ACos(acos_v, static_cast<TReal>(v));
+ return static_cast<qreal>(acos_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return acosf(float(v));
+ else
+# endif
+ return acos(v);
+#endif
+}
+
+inline qreal qAsin(qreal v)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal asin_v;
+ Math::ASin(asin_v, static_cast<TReal>(v));
+ return static_cast<qreal>(asin_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return asinf(float(v));
+ else
+# endif
+ return asin(v);
+#endif
+}
+
+inline qreal qAtan(qreal v)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal atan_v;
+ Math::ATan(atan_v, static_cast<TReal>(v));
+ return static_cast<qreal>(atan_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if(sizeof(qreal) == sizeof(float))
+ return atanf(float(v));
+ else
+# endif
+ return atan(v);
+#endif
+}
+
+inline qreal qAtan2(qreal x, qreal y)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal atan2_v;
+ Math::ATan(atan2_v, static_cast<TReal>(x), static_cast<TReal>(y));
+ return static_cast<qreal>(atan2_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if(sizeof(qreal) == sizeof(float))
+ return atan2f(float(x), float(y));
+ else
+# endif
+ return atan2(x, y);
#endif
- return acos(v);
}
inline qreal qSqrt(qreal v)
{
-#ifdef QT_USE_MATH_H_FLOATS
- if (sizeof(qreal) == sizeof(float))
- return sqrtf(float(v));
- else
+#ifdef Q_OS_SYMBIAN
+ TReal sqrt_v;
+ Math::Sqrt(sqrt_v, static_cast<TReal>(v));
+ return static_cast<qreal>(sqrt_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return sqrtf(float(v));
+ else
+# endif
+ return sqrt(v);
#endif
- return sqrt(v);
}
inline qreal qLn(qreal v)
@@ -126,14 +228,33 @@ inline qreal qLn(qreal v)
return log(v);
}
+inline qreal qExp(qreal v)
+{
+#ifdef Q_OS_SYMBIAN
+ TReal exp_v;
+ Math::Exp(exp_v, static_cast<TReal>(v));
+ return static_cast<qreal>(exp_v);
+#else
+ // only one signature
+ // exists, exp(double)
+ return exp(v);
+#endif
+}
+
inline qreal qPow(qreal x, qreal y)
{
-#ifdef QT_USE_MATH_H_FLOATS
- if (sizeof(qreal) == sizeof(float))
- return powf(float(x), float(y));
- else
+#ifdef Q_OS_SYMBIAN
+ TReal pow_v;
+ Math::Pow(pow_v, static_cast<TReal>(x), static_cast<TReal>(y));
+ return static_cast<qreal>(pow_v);
+#else
+# ifdef QT_USE_MATH_H_FLOATS
+ if (sizeof(qreal) == sizeof(float))
+ return powf(float(x), float(y));
+ else
+# endif
+ return pow(x, y);
#endif
- return pow(x, y);
}
#ifndef M_PI
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 6e6da19..72d6786 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -2648,6 +2648,7 @@ const char* QMetaClassInfo::value() const
*/
int QMetaObjectPrivate::originalClone(const QMetaObject *mobj, int local_method_index)
{
+ Q_ASSERT(local_method_index < get(mobj)->methodCount);
int handle = get(mobj)->methodData + 5 * local_method_index;
while (mobj->d.data[handle + 4] & MethodCloned) {
Q_ASSERT(local_method_index > 0);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 4321c59..305ec4f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -145,7 +145,7 @@ QObjectPrivate::QObjectPrivate(int version)
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
- connectedSignals = 0;
+ connectedSignals[0] = connectedSignals[1] = 0;
inEventHandler = false;
inThreadChangeEvent = false;
deleteWatch = 0;
@@ -153,15 +153,6 @@ QObjectPrivate::QObjectPrivate(int version)
hasGuards = false;
}
-#ifdef Q_CC_INTEL
-/* Workaround for a bug in win32-icc where it seems to inline ~QObjectPrivate too aggressive.
- When icc compiles QtGui, it inlines ~QObjectPrivate so that it would generate a call to
- ~QObjectData. However, ~QObjectData is not exported from QtCore, so it does not link.
- See also QTBUG-5145 for info on how this manifested itself.
- */
-# pragma auto_inline(off)
-#endif
-
QObjectPrivate::~QObjectPrivate()
{
delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
@@ -173,9 +164,6 @@ QObjectPrivate::~QObjectPrivate()
delete extraData;
#endif
}
-#ifdef Q_CC_INTEL
-# pragma auto_inline(on)
-#endif
int *QObjectPrivate::setDeleteWatch(QObjectPrivate *d, int *w) {
@@ -590,12 +578,13 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
protected functions connectNotify() and disconnectNotify() make
it possible to track connections.
- QObjects organize themselves in object trees. When you create a
- QObject with another object as parent, the object will
- automatically add itself to the parent's children() list. The
- parent takes ownership of the object; i.e., it will automatically
- delete its children in its destructor. You can look for an object
- by name and optionally type using findChild() or findChildren().
+ QObjects organize themselves in \l {Object Trees and Object
+ Ownership} {object trees}. When you create a QObject with another
+ object as parent, the object will automatically add itself to the
+ parent's children() list. The parent takes ownership of the
+ object; i.e., it will automatically delete its children in its
+ destructor. You can look for an object by name and optionally type
+ using findChild() or findChildren().
Every object has an objectName() and its class name can be found
via the corresponding metaObject() (see QMetaObject::className()).
@@ -694,7 +683,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object)
\l{Writing Source Code for Translation} document.
\sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
- {Object Trees and Object Ownership}
+ \sa {Object Trees and Object Ownership}
*/
/*!
@@ -2862,6 +2851,27 @@ void QObject::disconnectNotify(const char *)
{
}
+/* \internal
+ convert a signal index from the method range to the signal range
+ */
+static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index)
+{
+ if (signal_index < 0)
+ return signal_index;
+ while (metaObject && metaObject->methodOffset() > signal_index)
+ metaObject = metaObject->superClass();
+
+ if (metaObject) {
+ int signalOffset, methodOffset;
+ computeOffsets(metaObject, &signalOffset, &methodOffset);
+ if (signal_index < metaObject->methodCount())
+ signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
+ else
+ signal_index = signal_index - methodOffset + signalOffset;
+ }
+ return signal_index;
+}
+
/*!\internal
\a types is a 0-terminated vector of meta types for queued
connections.
@@ -2872,16 +2882,7 @@ void QObject::disconnectNotify(const char *)
bool QMetaObject::connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index, int type, int *types)
{
- if (signal_index > 0) {
- const QMetaObject *mo = sender->metaObject();
- while (mo && mo->methodOffset() > signal_index)
- mo = mo->superClass();
- if (mo) {
- int signalOffset, methodOffset;
- computeOffsets(mo, &signalOffset, &methodOffset);
- signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset;
- }
- }
+ signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
return QMetaObjectPrivate::connect(sender, signal_index,
receiver, method_index, type, types);
}
@@ -2936,9 +2937,9 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
QObjectPrivate *const sender_d = QObjectPrivate::get(s);
if (signal_index < 0) {
- sender_d->connectedSignals = ~ulong(0);
+ sender_d->connectedSignals[0] = sender_d->connectedSignals[1] = ~0;
} else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) {
- sender_d->connectedSignals |= ulong(1) << signal_index;
+ sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f));
}
return true;
@@ -2950,16 +2951,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
bool QMetaObject::disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index)
{
- if (signal_index > 0) {
- const QMetaObject *mo = sender->metaObject();
- while (mo && mo->methodOffset() > signal_index)
- mo = mo->superClass();
- if (mo) {
- int signalOffset, methodOffset;
- computeOffsets(mo, &signalOffset, &methodOffset);
- signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset;
- }
- }
+ signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
return QMetaObjectPrivate::disconnect(sender, signal_index,
receiver, method_index);
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 340498f..1a178e2 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -91,7 +91,11 @@ template<typename T> inline QList<T> qFindChildren(const QObject *, const QRegEx
# endif
#endif
-class QObjectData {
+class
+#if defined(__INTEL_COMPILER) && defined(Q_OS_WIN)
+Q_CORE_EXPORT
+#endif
+QObjectData {
public:
virtual ~QObjectData() = 0;
QObject *q_ptr;
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index f899c78..d1841be 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -172,7 +172,7 @@ public:
}
int signalIndex(const char *signalName) const;
- inline bool isSignalConnected(int signalIdx) const;
+ inline bool isSignalConnected(uint signalIdx) const;
public:
QString objectName;
@@ -183,7 +183,7 @@ public:
Connection *senders; // linked list of connections connected to this object
Sender *currentSender; // object currently activating the object
- mutable ulong connectedSignals;
+ mutable quint32 connectedSignals[2];
#ifdef QT3_SUPPORT
QList<QObject *> pendingChildInsertedEvents;
@@ -205,6 +205,7 @@ public:
int *deleteWatch;
};
+
/*! \internal
Returns true if the signal with index \a signal_index from object \a sender is connected.
@@ -213,12 +214,12 @@ public:
\a signal_index must be the index returned by QObjectPrivate::signalIndex;
*/
-inline bool QObjectPrivate::isSignalConnected(int signal_index) const
+inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
{
- return signal_index >= (int)sizeof(connectedSignals) * 8
+ return signal_index >= sizeof(connectedSignals) * 8
|| qt_signal_spy_callback_set.signal_begin_callback
|| qt_signal_spy_callback_set.signal_end_callback
- || (connectedSignals & (ulong(1) << signal_index));
+ || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f)));
}
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 3c10788..74ff17f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -458,7 +458,7 @@ inline void qVariantSetValue(QVariant &v, const T &t)
//if possible we reuse the current QVariant private
const uint type = qMetaTypeId<T>(reinterpret_cast<T *>(0));
QVariant::Private &d = v.data_ptr();
- if (v.isDetached() && (type <= uint(QVariant::Char) || type == d.type)) {
+ if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
d.type = type;
d.is_null = false;
T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 6496876..ea0254b 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -744,7 +744,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
pluginState = IsNotAPlugin; // be pessimistic
- if ((qt_version > QT_VERSION) || ((QT_VERSION & 0xff0000) > (qt_version & 0xff0000))) {
+ if ((qt_version & 0x00ff00) > (QT_VERSION & 0x00ff00) || (qt_version & 0xff0000) != (QT_VERSION & 0xff0000)) {
if (qt_debug_component()) {
qWarning("In %s:\n"
" Plugin uses incompatible Qt library (%d.%d.%d) [%s]",
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index af68434..3db308f 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -202,7 +202,7 @@ public:
QStack<QEventLoop *> eventLoops;
QPostEventList postEventList;
bool canWait;
- QMap<int, void *> tls;
+ QVector<void *> tls;
QMutex mutex;
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 21b5e65..0309c67 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -74,6 +74,10 @@
# endif
#endif
+#ifdef Q_OS_HPUX
+#include <sys/pstat.h>
+#endif
+
#if defined(Q_OS_MAC)
# ifdef qDebug
# define old_qDebug qDebug
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 8b1f255..a7d53d0 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -71,27 +71,32 @@ void qtsDebug(const char *fmt, ...)
# define DEBUG_MSG if(false)qDebug
#endif
-static QBasicAtomicInt idCounter = Q_BASIC_ATOMIC_INITIALIZER(INT_MAX);
Q_GLOBAL_STATIC(QMutex, mutex)
-typedef QMap<int, void (*)(void *)> DestructorMap;
+typedef QVector<void (*)(void *)> DestructorMap;
Q_GLOBAL_STATIC(DestructorMap, destructors)
QThreadStorageData::QThreadStorageData(void (*func)(void *))
- : id(idCounter.fetchAndAddRelaxed(-1))
{
QMutexLocker locker(mutex());
- destructors()->insert(id, func);
-
+ DestructorMap *destr = destructors();
+ for (id = 0; id < destr->count(); id++) {
+ if (destr->at(id) == 0)
+ break;
+ }
+ if (id == destr->count()) {
+ destr->append(func);
+ } else {
+ (*destr)[id] = func;
+ }
DEBUG_MSG("QThreadStorageData: Allocated id %d, destructor %p", id, func);
}
QThreadStorageData::~QThreadStorageData()
{
+ DEBUG_MSG("QThreadStorageData: Released id %d", id);
QMutexLocker locker(mutex());
if (destructors())
- destructors()->remove(id);
-
- DEBUG_MSG("QThreadStorageData: Released id %d", id);
+ (*destructors())[id] = 0;
}
void **QThreadStorageData::get() const
@@ -101,14 +106,17 @@ void **QThreadStorageData::get() const
qWarning("QThreadStorage::get: QThreadStorage can only be used with threads started with QThread");
return 0;
}
- QMap<int, void *>::const_iterator it = data->tls.constFind(id);
+ QVector<void *> &tls = data->tls;
+ if (tls.size() <= id)
+ tls.resize(id + 1);
+ void **v = &tls[id];
+
DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p",
id,
- it != data->tls.end() ? it.value() : 0,
+ *v,
data->thread);
- // const_cast below is a bit evil - but we have to make sure not to detach here
- // otherwise we'll go bonkers in oom situations
- return it != data->tls.constEnd() && it.value() != 0 ? const_cast<void **>(&it.value()) : 0;
+
+ return *v ? v : 0;
}
void **QThreadStorageData::set(void *p)
@@ -118,51 +126,46 @@ void **QThreadStorageData::set(void *p)
qWarning("QThreadStorage::set: QThreadStorage can only be used with threads started with QThread");
return 0;
}
+ QVector<void *> &tls = data->tls;
+ if (tls.size() <= id)
+ tls.resize(id + 1);
+
+ void *&value = tls[id];
+ // delete any previous data
+ if (value != 0) {
+ DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
+ id,
+ value,
+ data->thread);
- QMap<int, void *>::iterator it = data->tls.find(id);
- if (it != data->tls.end()) {
- // delete any previous data
- if (it.value() != 0) {
- DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
- id,
- it.value(),
- data->thread);
-
- void *q = it.value();
- it.value() = 0;
-
- QMutexLocker locker(mutex());
- void (*destructor)(void *) = destructors()->value(id);
- locker.unlock();
+ QMutexLocker locker(mutex());
+ void (*destructor)(void *) = destructors()->value(id);
+ locker.unlock();
- destructor(q);
- }
+ void *q = value;
+ value = 0;
- // store new data
- it.value() = p;
- DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p);
- } else {
- it = data->tls.insert(id, p);
- DEBUG_MSG("QThreadStorageData: Inserted storage %d, data %p, for thread %p", id, p, data->thread);
+ destructor(q);
}
- return &it.value();
+ // store new data
+ value = p;
+ DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p);
+ return &value;
}
void QThreadStorageData::finish(void **p)
{
- QMap<int, void *> *tls = reinterpret_cast<QMap<int, void *> *>(p);
+ QVector<void *> *tls = reinterpret_cast<QVector<void *> *>(p);
if (!tls || tls->isEmpty() || !mutex())
return; // nothing to do
DEBUG_MSG("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread());
- QMap<int, void *>::iterator it = tls->begin();
- while (it != tls->end()) {
- int id = it.key();
- void *q = it.value();
- it.value() = 0;
- ++it;
+ for(int i = tls->size() - 1; i >= 0; i--) {
+ void *&value = (*tls)[i];
+ void *q = value;
+ value = 0;
if (!q) {
// data already deleted
@@ -170,16 +173,16 @@ void QThreadStorageData::finish(void **p)
}
QMutexLocker locker(mutex());
- void (*destructor)(void *) = destructors()->value(id);
+ void (*destructor)(void *) = destructors()->value(i);
locker.unlock();
if (!destructor) {
if (QThread::currentThread())
qWarning("QThreadStorage: Thread %p exited after QThreadStorage %d destroyed",
- QThread::currentThread(), id);
+ QThread::currentThread(), i);
continue;
}
- destructor(q);
+ destructor(q); //crash here might mean the thread exited after qthreadstorage was destroyed
}
tls->clear();
}
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
index 46e20b1..66f9f73 100644
--- a/src/corelib/tools/qcache.h
+++ b/src/corelib/tools/qcache.h
@@ -70,8 +70,9 @@ class QCache
if (l == &n) l = n.p;
if (f == &n) f = n.n;
total -= n.c;
- delete n.t;
+ T *obj = n.t;
hash.remove(*n.keyPtr);
+ delete obj;
}
inline T *relink(const Key &key) {
typename QHash<Key, Node>::iterator i = hash.find(key);
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 1918229..2de03dc 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -69,18 +69,18 @@ inline uint qHash(int key) { return uint(key); }
inline uint qHash(ulong key)
{
if (sizeof(ulong) > sizeof(uint)) {
- return uint((key >> (8 * sizeof(uint) - 1)) ^ key);
+ return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U));
} else {
- return uint(key);
+ return uint(key & (~0U));
}
}
inline uint qHash(long key) { return qHash(ulong(key)); }
inline uint qHash(quint64 key)
{
if (sizeof(quint64) > sizeof(uint)) {
- return uint((key >> (8 * sizeof(uint) - 1)) ^ key);
+ return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U));
} else {
- return uint(key);
+ return uint(key & (~0U));
}
}
inline uint qHash(qint64 key) { return qHash(quint64(key)); }
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index d0afb7a..8112757 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -574,7 +574,7 @@ qreal QLineF::angle() const
const qreal dx = pt2.x() - pt1.x();
const qreal dy = pt2.y() - pt1.y();
- const qreal theta = atan2(-dy, dx) * 360.0 / M_2PI;
+ const qreal theta = qAtan2(-dy, dx) * 360.0 / M_2PI;
const qreal theta_normalized = theta < 0 ? theta + 360 : theta;
@@ -814,7 +814,7 @@ qreal QLineF::angle(const QLineF &l) const
qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length());
qreal rad = 0;
// only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases)
- if (cos_line >= -1.0 && cos_line <= 1.0) rad = acos( cos_line );
+ if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line );
return rad * 360 / M_2PI;
}
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 4a66b92..8645f17 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -1187,14 +1187,14 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
}
case DateFormatLong:
case DateFormatShort:
- return macToQtFormat(getMacDateFormat(type == DateFormatShort
+ return getMacDateFormat(type == DateFormatShort
? kCFDateFormatterShortStyle
- : kCFDateFormatterLongStyle));
+ : kCFDateFormatterLongStyle);
case TimeFormatLong:
case TimeFormatShort:
- return macToQtFormat(getMacTimeFormat(type == TimeFormatShort
+ return getMacTimeFormat(type == TimeFormatShort
? kCFDateFormatterShortStyle
- : kCFDateFormatterLongStyle));
+ : kCFDateFormatterLongStyle);
case DayNameLong:
case DayNameShort:
return macDayName(in.toInt(), (type == DayNameShort));
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index 2bad40e..8a46b98 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -119,7 +119,9 @@ public:
#endif
int matchedLength() const;
#ifndef QT_NO_REGEXP_CAPTURE
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numCaptures() const;
+#endif
int captureCount() const;
QStringList capturedTexts() const;
QStringList capturedTexts();
diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp
index cd3483d..ce49e3f 100644
--- a/src/corelib/tools/qtimeline.cpp
+++ b/src/corelib/tools/qtimeline.cpp
@@ -125,7 +125,7 @@ void QTimeLinePrivate::setCurrentTime(int msecs)
#ifdef QTIMELINE_DEBUG
qDebug() << "QTimeLinePrivate::setCurrentTime: frameForTime" << currentTime << currentFrame;
#endif
- if (lastValue != q->currentValue())
+ if (!qFuzzyCompare(lastValue, q->currentValue()))
emit q->valueChanged(q->currentValue());
if (lastFrame != currentFrame) {
const int transitionframe = (direction == QTimeLine::Forward ? endFrame : startFrame);
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 201e7b3..e00cf3f 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -219,7 +219,7 @@ public:
inline const_iterator &operator--() { i--; return *this; }
inline const_iterator operator--(int) { T *n = i; i--; return n; }
inline const_iterator &operator+=(int j) { i+=j; return *this; }
- inline const_iterator &operator-=(int j) { i+=j; return *this; }
+ inline const_iterator &operator-=(int j) { i-=j; return *this; }
inline const_iterator operator+(int j) const { return const_iterator(i+j); }
inline const_iterator operator-(int j) const { return const_iterator(i-j); }
inline int operator-(const_iterator j) const { return i - j.i; }
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index 994da10..ff0a93e 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -561,13 +561,7 @@ void QDBusAbstractInterface::connectNotify(const char *signal)
QDBusConnectionPrivate *conn = d->connectionPrivate();
if (conn) {
- // do we know what our owner is?
- QString owner;
- if (!d->service.isEmpty() && d->currentOwner.isNull())
- owner = QLatin1String("");
- else
- owner = d->currentOwner;
- conn->connectRelay(d->service, owner, d->path, d->interface,
+ conn->connectRelay(d->service, d->path, d->interface,
this, signal);
}
}
@@ -585,7 +579,7 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal)
QDBusConnectionPrivate *conn = d->connectionPrivate();
if (conn)
- conn->disconnectRelay(d->service, d->currentOwner, d->path, d->interface,
+ conn->disconnectRelay(d->service, d->path, d->interface,
this, signal);
}
diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h
index 47c5e62..17302b4 100644
--- a/src/dbus/qdbusargument_p.h
+++ b/src/dbus/qdbusargument_p.h
@@ -54,7 +54,7 @@
//
#include <qdbusargument.h>
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index d7088ff..47893cc 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -619,10 +619,8 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const
if (interface.isEmpty() && name.isEmpty())
return false;
- QString owner = d->getNameOwner(service); // we don't care if the owner is empty
- // it might get started later
QDBusWriteLocker locker(ConnectAction, d);
- return d->connectSignal(service, owner, path, interface, name, argumentMatch, signature, receiver, slot);
+ return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
}
/*!
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index b65e101..32e057c 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -67,7 +67,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include <qdbusmessage.h>
@@ -119,7 +119,7 @@ public:
struct SignalHook
{
inline SignalHook() : obj(0), midx(-1) { }
- QString owner, service, path, signature;
+ QString service, path, signature;
QObject* obj;
int midx;
QList<int> params;
@@ -155,7 +155,13 @@ public:
typedef QMultiHash<QString, SignalHook> SignalHookHash;
typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
typedef QHash<QByteArray, int> MatchRefCountHash;
- typedef QHash<QString, int> WatchedServicesHash;
+
+ struct WatchedServiceData {
+ WatchedServiceData() : refcount(0) {}
+ QString owner;
+ int refcount;
+ };
+ typedef QHash<QString, WatchedServiceData> WatchedServicesHash;
public:
// public methods are entry points from other objects
@@ -177,7 +183,7 @@ public:
QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1);
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
const char *returnMethod, const char *errorMethod, int timeout = -1);
- bool connectSignal(const QString &service, const QString &owner, const QString &path, const QString& interface,
+ bool connectSignal(const QString &service, const QString &path, const QString& interface,
const QString &name, const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot);
void connectSignal(const QString &key, const SignalHook &hook);
@@ -186,10 +192,10 @@ public:
const QString &name, const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot);
void registerObject(const ObjectTreeNode *node);
- void connectRelay(const QString &service, const QString &currentOwner,
+ void connectRelay(const QString &service,
const QString &path, const QString &interface,
QDBusAbstractInterface *receiver, const char *signal);
- void disconnectRelay(const QString &service, const QString &currentOwner,
+ void disconnectRelay(const QString &service,
const QString &path, const QString &interface,
QDBusAbstractInterface *receiver, const char *signal);
@@ -223,6 +229,8 @@ private:
bool isServiceRegisteredByThread(const QString &serviceName) const;
+ QString getNameOwnerNoCache(const QString &service);
+
protected:
void customEvent(QEvent *e);
void timerEvent(QTimerEvent *e);
@@ -271,7 +279,7 @@ public:
QDBusError lastError;
QStringList serviceNames;
- WatchedServicesHash watchedServiceNames;
+ WatchedServicesHash watchedServices;
SignalHookHash signalHooks;
MatchRefCountHash matchRefCounts;
ObjectTreeNode rootNode;
@@ -284,7 +292,7 @@ public:
// static methods
static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params);
static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
- const QString &service, const QString &owner,
+ const QString &service,
const QString &path, const QString &interface, const QString &name,
const QStringList &argMatch,
QObject *receiver, const char *signal, int minMIdx,
diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp
index 0f9a67f..ec61859 100644
--- a/src/dbus/qdbusconnectioninterface.cpp
+++ b/src/dbus/qdbusconnectioninterface.cpp
@@ -49,7 +49,7 @@
#include <QtCore/QVariant>
#include <QtCore/QDebug>
-#include <qdbus_symbols_p.h> // for the DBUS_* constants
+#include "qdbus_symbols_p.h" // for the DBUS_* constants
QT_BEGIN_NAMESPACE
diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp
index 5c2fa2b..a48b878 100644
--- a/src/dbus/qdbuserror.cpp
+++ b/src/dbus/qdbuserror.cpp
@@ -44,7 +44,7 @@
#include <qdebug.h>
#include <qvarlengtharray.h>
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include "qdbusmessage.h"
#include "qdbusmessage_p.h"
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 40febc4..ea02005 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -390,7 +390,7 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
} // extern "C"
-static QByteArray buildMatchRule(const QString &service, const QString & /*owner*/,
+static QByteArray buildMatchRule(const QString &service,
const QString &objectPath, const QString &interface,
const QString &member, const QStringList &argMatch, const QString & /*signature*/)
{
@@ -523,7 +523,7 @@ qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message);
- qDBusDebug() << QThread::currentThread() << "got message:" << amsg;
+ qDBusDebug() << d << "got message:" << amsg;
return d->handleMessage(amsg) ?
DBUS_HANDLER_RESULT_HANDLED :
@@ -913,7 +913,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
if (msg.isReplyRequired() && !msg.isDelayedReply()) {
if (!fail) {
// normal reply
- qDBusDebug() << QThread::currentThread() << "Automatically sending reply:" << outputArgs;
+ qDBusDebug() << this << "Automatically sending reply:" << outputArgs;
send(msg.createReply(outputArgs));
} else {
// generate internal error
@@ -947,7 +947,6 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
QDBusMetaTypeId::init();
rootNode.flags = 0;
- watchedServiceNames[QLatin1String(DBUS_SERVICE_DBUS)] = 1;
}
QDBusConnectionPrivate::~QDBusConnectionPrivate()
@@ -1179,11 +1178,15 @@ void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name,
{
Q_UNUSED(oldOwner);
QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this);
- QMutableHashIterator<QString, SignalHook> it(signalHooks);
- it.toFront();
- while (it.hasNext())
- if (it.next().value().service == name)
- it.value().owner = newOwner;
+ WatchedServicesHash::Iterator it = watchedServices.find(name);
+ if (it == watchedServices.end())
+ return;
+ if (oldOwner != it->owner)
+ qWarning("QDBusConnection: name '%s' had owner '%s' but we thought it was '%s'",
+ qPrintable(name), qPrintable(oldOwner), qPrintable(it->owner));
+
+ qDBusDebug() << this << "Updating name" << name << "from" << oldOwner << "to" << newOwner;
+ it->owner = newOwner;
}
int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedName,
@@ -1201,7 +1204,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN
}
bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
- const QString &service, const QString &owner,
+ const QString &service,
const QString &path, const QString &interface, const QString &name,
const QStringList &argMatch,
QObject *receiver, const char *signal, int minMIdx,
@@ -1220,7 +1223,6 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo
}
hook.service = service;
- hook.owner = owner; // we don't care if the service has an owner yet
hook.path = path;
hook.obj = receiver;
hook.argumentMatch = argMatch;
@@ -1245,7 +1247,7 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo
hook.signature += QLatin1String( QDBusMetaType::typeToSignature( hook.params.at(i) ) );
}
- hook.matchRule = buildMatchRule(service, owner, path, interface, mname, argMatch, hook.signature);
+ hook.matchRule = buildMatchRule(service, path, interface, mname, argMatch, hook.signature);
return true; // connect to this signal
}
@@ -1488,8 +1490,14 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage
//qDBusDebug() << signalHooks.keys();
for ( ; it != end && it.key() == key; ++it) {
const SignalHook &hook = it.value();
- if (!hook.owner.isNull() && hook.owner != msg.service())
- continue;
+ if (!hook.service.isEmpty()) {
+ const QString owner =
+ shouldWatchService(hook.service) ?
+ watchedServices.value(hook.service).owner :
+ hook.service;
+ if (owner != msg.service())
+ continue;
+ }
if (!hook.path.isEmpty() && hook.path != msg.path())
continue;
if (!hook.signature.isEmpty() && hook.signature != msg.signature())
@@ -1652,15 +1660,18 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError
}
QString busService = QLatin1String(DBUS_SERVICE_DBUS);
- connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(),
+ WatchedServicesHash::mapped_type &bus = watchedServices[busService];
+ bus.refcount = 1;
+ bus.owner = getNameOwnerNoCache(busService);
+ connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(),
this, SLOT(registerService(QString)));
- connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(),
+ connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(),
this, SLOT(unregisterService(QString)));
q_dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0);
- //qDebug("base service: %s", service);
+ qDBusDebug() << this << ": connected successfully";
// schedule a dispatch:
QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);
@@ -1695,7 +1706,7 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
msg = QDBusMessagePrivate::fromDBusMessage(reply);
q_dbus_message_unref(reply);
}
- qDBusDebug() << QThread::currentThread() << "got message reply (async):" << msg;
+ qDBusDebug() << connection << "got message reply (async):" << msg;
// Check if the reply has the expected signature
call->checkReceivedSignature();
@@ -1763,7 +1774,7 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message)
q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything
- qDBusDebug() << QThread::currentThread() << "sending message (no reply):" << message;
+ qDBusDebug() << this << "sending message (no reply):" << message;
checkThread();
bool isOk = q_dbus_connection_send(connection, msg, 0);
int serial = 0;
@@ -1795,7 +1806,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
return QDBusMessage::createError(err);
}
- qDBusDebug() << QThread::currentThread() << "sending message (blocking):" << message;
+ qDBusDebug() << this << "sending message (blocking):" << message;
QDBusErrorInternal error;
DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error);
@@ -1808,7 +1819,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(reply);
q_dbus_message_unref(reply);
- qDBusDebug() << QThread::currentThread() << "got message reply (blocking):" << amsg;
+ qDBusDebug() << this << "got message reply (blocking):" << amsg;
return amsg;
} else { // use the event loop
@@ -1835,7 +1846,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(const QDBusMessage &message)
{
- qDBusDebug() << QThread::currentThread() << "sending message via local-loop:" << message;
+ qDBusDebug() << this << "sending message via local-loop:" << message;
QDBusMessage localCallMsg = QDBusMessagePrivate::makeLocal(*this, message);
bool handled = handleMessage(localCallMsg);
@@ -1862,7 +1873,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(const QDBusMessage &mess
}
// there is a reply
- qDBusDebug() << QThread::currentThread() << "got message via local-loop:" << localReplyMsg;
+ qDBusDebug() << this << "got message via local-loop:" << localReplyMsg;
return localReplyMsg;
}
@@ -1896,7 +1907,7 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM
return pcall;
}
- qDBusDebug() << QThread::currentThread() << "sending message (async):" << message;
+ qDBusDebug() << this << "sending message (async):" << message;
DBusPendingCall *pending = 0;
QDBusDispatchLocker locker(SendWithReplyAsyncAction, this);
@@ -1968,7 +1979,7 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj
return 1;
}
-bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString &owner,
+bool QDBusConnectionPrivate::connectSignal(const QString &service,
const QString &path, const QString &interface, const QString &name,
const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot)
@@ -1981,7 +1992,7 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString
name2.detach();
hook.signature = signature;
- if (!prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false))
+ if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0, false))
return false; // don't connect
// avoid duplicating:
@@ -1990,7 +2001,6 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString
for ( ; it != end && it.key() == key; ++it) {
const QDBusConnectionPrivate::SignalHook &entry = it.value();
if (entry.service == hook.service &&
- entry.owner == hook.owner &&
entry.path == hook.path &&
entry.signature == hook.signature &&
entry.obj == hook.obj &&
@@ -2035,16 +2045,19 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook
// Successfully connected the signal
// Do we need to watch for this name?
if (shouldWatchService(hook.service)) {
- WatchedServicesHash::Iterator it = watchedServiceNames.find(hook.service);
- if (it != watchedServiceNames.end()) {
+ WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
+ if (data.refcount) {
// already watching
- ++it.value();
+ ++data.refcount;
} else {
// we need to watch for this service changing
QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
- connectSignal(dbusServerService, dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
+ connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
+ data.owner = getNameOwnerNoCache(hook.service);
+ qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:"
+ << data.owner << ")";
}
}
}
@@ -2064,7 +2077,7 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
name2.detach();
hook.signature = signature;
- if (!prepareHook(hook, key, service, QString(), path, interface, name, argumentMatch, receiver, slot, 0, false))
+ if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0, false))
return false; // don't disconnect
// avoid duplicating:
@@ -2073,7 +2086,6 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
for ( ; it != end && it.key() == key; ++it) {
const QDBusConnectionPrivate::SignalHook &entry = it.value();
if (entry.service == hook.service &&
- //entry.owner == hook.owner &&
entry.path == hook.path &&
entry.signature == hook.signature &&
entry.obj == hook.obj &&
@@ -2093,16 +2105,16 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it)
{
const SignalHook &hook = it.value();
- WatchedServicesHash::Iterator sit = watchedServiceNames.find(hook.service);
- if (sit != watchedServiceNames.end()) {
- if (sit.value() == 1) {
- watchedServiceNames.erase(sit);
+ WatchedServicesHash::Iterator sit = watchedServices.find(hook.service);
+ if (sit != watchedServices.end()) {
+ if (sit.value().refcount == 1) {
+ watchedServices.erase(sit);
QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
} else {
- --sit.value();
+ --sit.value().refcount;
}
}
@@ -2154,7 +2166,7 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node)
}
}
-void QDBusConnectionPrivate::connectRelay(const QString &service, const QString &owner,
+void QDBusConnectionPrivate::connectRelay(const QString &service,
const QString &path, const QString &interface,
QDBusAbstractInterface *receiver,
const char *signal)
@@ -2164,7 +2176,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString
SignalHook hook;
QString key;
- if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal,
+ if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, signal,
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
return; // don't connect
@@ -2175,7 +2187,6 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString
for ( ; it != end && it.key() == key; ++it) {
const SignalHook &entry = it.value();
if (entry.service == hook.service &&
- entry.owner == hook.owner &&
entry.path == hook.path &&
entry.signature == hook.signature &&
entry.obj == hook.obj &&
@@ -2186,7 +2197,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString
connectSignal(key, hook);
}
-void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QString &owner,
+void QDBusConnectionPrivate::disconnectRelay(const QString &service,
const QString &path, const QString &interface,
QDBusAbstractInterface *receiver,
const char *signal)
@@ -2196,7 +2207,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QStri
SignalHook hook;
QString key;
- if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal,
+ if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, signal,
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
return; // don't connect
@@ -2207,7 +2218,6 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QStri
for ( ; it != end && it.key() == key; ++it) {
const SignalHook &entry = it.value();
if (entry.service == hook.service &&
- entry.owner == hook.owner &&
entry.path == hook.path &&
entry.signature == hook.signature &&
entry.obj == hook.obj &&
@@ -2225,9 +2235,23 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName)
{
if (QDBusUtil::isValidUniqueConnectionName(serviceName))
return serviceName;
- if (!connection || !QDBusUtil::isValidBusName(serviceName))
+ if (!connection)
return QString();
+ {
+ // acquire a read lock for the cache
+ QReadLocker locker(&lock);
+ WatchedServicesHash::ConstIterator it = watchedServices.constFind(serviceName);
+ if (it != watchedServices.constEnd())
+ return it->owner;
+ }
+
+ // not cached
+ return getNameOwnerNoCache(serviceName);
+}
+
+QString QDBusConnectionPrivate::getNameOwnerNoCache(const QString &serviceName)
+{
QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS),
QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS),
QLatin1String("GetNameOwner"));
diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h
index 5b18aca..85c6cb2 100644
--- a/src/dbus/qdbusintegrator_p.h
+++ b/src/dbus/qdbusintegrator_p.h
@@ -54,7 +54,7 @@
#ifndef QDBUSINTEGRATOR_P_H
#define QDBUSINTEGRATOR_P_H
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include "qcoreevent.h"
#include "qeventloop.h"
diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp
index d0a693f..c05e6a9 100644
--- a/src/dbus/qdbusinterface.cpp
+++ b/src/dbus/qdbusinterface.cpp
@@ -41,7 +41,7 @@
#include "qdbusinterface.h"
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include <QtCore/qpointer.h>
#include <QtCore/qstringlist.h>
diff --git a/src/dbus/qdbusinterface_p.h b/src/dbus/qdbusinterface_p.h
index 3d11af1..a601608 100644
--- a/src/dbus/qdbusinterface_p.h
+++ b/src/dbus/qdbusinterface_p.h
@@ -54,8 +54,8 @@
#ifndef QDBUSINTERFACEPRIVATE_H
#define QDBUSINTERFACEPRIVATE_H
-#include <qdbusabstractinterface_p.h>
-#include <qdbusmetaobject_p.h>
+#include "qdbusabstractinterface_p.h"
+#include "qdbusmetaobject_p.h"
#include <qdbusinterface.h>
QT_BEGIN_NAMESPACE
diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp
index acd04d3..37110c5 100644
--- a/src/dbus/qdbusinternalfilters.cpp
+++ b/src/dbus/qdbusinternalfilters.cpp
@@ -41,7 +41,7 @@
#include "qdbusconnection_p.h"
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include <QtCore/qcoreapplication.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp
index d732ad0..28cec7d 100644
--- a/src/dbus/qdbusmarshaller.cpp
+++ b/src/dbus/qdbusmarshaller.cpp
@@ -387,7 +387,6 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg)
switch (*signature) {
#ifdef __OPTIMIZE__
case DBUS_TYPE_BYTE:
- case DBUS_TYPE_BOOLEAN:
case DBUS_TYPE_INT16:
case DBUS_TYPE_UINT16:
case DBUS_TYPE_INT32:
@@ -397,6 +396,9 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg)
case DBUS_TYPE_DOUBLE:
qIterAppend(&iterator, ba, *signature, arg.constData());
return true;
+ case DBUS_TYPE_BOOLEAN:
+ append( arg.toBool() );
+ return true;
#else
case DBUS_TYPE_BYTE:
append( qvariant_cast<uchar>(arg) );
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index 4f1950b..a37ba1f 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -44,7 +44,7 @@
#include <qdebug.h>
#include <qstringlist.h>
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include "qdbusargument_p.h"
#include "qdbuserror.h"
diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp
index 237aea3..afa3bbf 100644
--- a/src/dbus/qdbusmetatype.cpp
+++ b/src/dbus/qdbusmetatype.cpp
@@ -42,7 +42,7 @@
#include "qdbusmetatype.h"
#include <string.h>
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include <qbytearray.h>
#include <qglobal.h>
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index ef50b04..9c768ed 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -310,7 +310,7 @@ QDBusPendingCall &QDBusPendingCall::operator=(const QDBusPendingCall &other)
bool QDBusPendingCall::isFinished() const
{
- return d && (d->replyMessage.type() != QDBusMessage::InvalidMessage);
+ return !d || (d->replyMessage.type() != QDBusMessage::InvalidMessage);
}
void QDBusPendingCall::waitForFinished()
diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h
index b7f54e4..4f90c98 100644
--- a/src/dbus/qdbuspendingreply.h
+++ b/src/dbus/qdbuspendingreply.h
@@ -188,6 +188,7 @@ public:
private:
inline void calculateMetaTypes()
{
+ if (!d) return;
int typeIds[Count > 0 ? Count : 1]; // use at least one since zero-sized arrays aren't valid
ForEach::fillMetaTypes(typeIds);
setMetaTypes(Count, typeIds);
diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp
index bf5a739..01b1dbd 100644
--- a/src/dbus/qdbusutil.cpp
+++ b/src/dbus/qdbusutil.cpp
@@ -41,7 +41,7 @@
#include "qdbusutil_p.h"
-#include <qdbus_symbols_p.h>
+#include "qdbus_symbols_p.h"
#include <QtCore/qstringlist.h>
diff --git a/src/dbus/qdbusxmlparser_p.h b/src/dbus/qdbusxmlparser_p.h
index 3dbae1b..1a0523b 100644
--- a/src/dbus/qdbusxmlparser_p.h
+++ b/src/dbus/qdbusxmlparser_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qmap.h>
#include <QtXml/qdom.h>
#include <qdbusmacros.h>
-#include <qdbusintrospection_p.h>
+#include "qdbusintrospection_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri
index b9fad41..63f64a2 100644
--- a/src/gui/dialogs/dialogs.pri
+++ b/src/gui/dialogs/dialogs.pri
@@ -28,13 +28,27 @@ HEADERS += \
dialogs/qprintpreviewdialog.h
!embedded:mac {
- OBJECTIVE_SOURCES += dialogs/qcolordialog_mac.mm \
- dialogs/qfiledialog_mac.mm \
+ OBJECTIVE_SOURCES += dialogs/qfiledialog_mac.mm \
dialogs/qfontdialog_mac.mm \
dialogs/qnspanelproxy_mac.mm \
dialogs/qpagesetupdialog_mac.mm \
dialogs/qprintdialog_mac.mm
+
+# Compile qcolordialog_mac.mm with exception support, disregarding the -no-exceptions
+# configure option. (qcolordialog_mac needs to catch exceptions thrown by cocoa)
+ EXCEPTION_SOURCES = dialogs/qcolordialog_mac.mm
+ exceptions_compiler.commands = $$QMAKE_CXX -c
+ exceptions_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ exceptions_compiler.commands += -fexceptions
+ exceptions_compiler.dependency_type = TYPE_C
+ exceptions_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ exceptions_compiler.input = EXCEPTION_SOURCES
+ exceptions_compiler.variable_out = OBJECTS
+ exceptions_compiler.name = compiling[exceptopns] ${QMAKE_FILE_IN}
+ silent:exceptions_compiler.commands = @echo compiling[exceptopns] ${QMAKE_FILE_IN} && $$exceptions_compiler.commands
+ QMAKE_EXTRA_COMPILERS += exceptions_compiler
}
+
win32 {
HEADERS += dialogs/qwizard_win_p.h
SOURCES += dialogs/qdialogsbinarycompat_win.cpp \
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm
index 53d2e1e..5753954 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/gui/dialogs/qcolordialog_mac.mm
@@ -79,6 +79,7 @@ QT_USE_NAMESPACE
BOOL mHackedPanel;
NSInteger mResultCode;
BOOL mDialogIsExecuting;
+ BOOL mResultSet;
}
- (id)initWithColorPanel:(NSColorPanel *)panel
stolenContentView:(NSView *)stolenContentView
@@ -116,6 +117,7 @@ QT_USE_NAMESPACE
mHackedPanel = (okButton != 0);
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
+ mResultSet = false;
if (mHackedPanel) {
[self relayout];
@@ -159,11 +161,13 @@ QT_USE_NAMESPACE
- (BOOL)windowShouldClose:(id)window
{
Q_UNUSED(window);
- if (mHackedPanel) {
- [self onCancelClicked];
- } else {
+ if (!mHackedPanel)
[self updateQtColor];
+ if (mDialogIsExecuting) {
[self finishOffWithCode:NSCancelButton];
+ } else {
+ mResultSet = true;
+ mPriv->colorDialog()->reject();
}
return true;
}
@@ -240,11 +244,12 @@ QT_USE_NAMESPACE
- (void)onCancelClicked
{
- Q_ASSERT(mHackedPanel);
- [[mStolenContentView window] close];
- delete mQtColor;
- mQtColor = new QColor();
- [self finishOffWithCode:NSCancelButton];
+ if (mHackedPanel) {
+ [[mStolenContentView window] close];
+ delete mQtColor;
+ mQtColor = new QColor();
+ [self finishOffWithCode:NSCancelButton];
+ }
}
- (void)updateQtColor
@@ -306,10 +311,16 @@ QT_USE_NAMESPACE
} else {
// Since we are not in a modal event loop, we can safely close
// down QColorDialog
- if (mResultCode == NSCancelButton)
- mPriv->colorDialog()->reject();
- else
- mPriv->colorDialog()->accept();
+ // Calling accept() or reject() can in turn call closeCocoaColorPanel.
+ // This check will prevent any such recursion.
+ if (!mResultSet) {
+ mResultSet = true;
+ if (mResultCode == NSCancelButton) {
+ mPriv->colorDialog()->reject();
+ } else {
+ mPriv->colorDialog()->accept();
+ }
+ }
}
}
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
index 0c467cd..31bab2b 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -394,7 +394,9 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
}
[mFontPanel setDelegate:nil];
[[NSFontManager sharedFontManager] setDelegate:nil];
+#ifdef QT_MAC_USE_COCOA
[[NSFontManager sharedFontManager] setTarget:nil];
+#endif
}
@end
@@ -518,7 +520,9 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial,
extraHeight:dialogExtraHeight];
[ourPanel setDelegate:delegate];
[[NSFontManager sharedFontManager] setDelegate:delegate];
+#ifdef QT_MAC_USE_COCOA
[[NSFontManager sharedFontManager] setTarget:delegate];
+#endif
setFont(delegate, initial);
// hack to get correct initial layout
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index a318c43..8ec8d1c 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -188,6 +188,9 @@ public:
bool autoAddOkButton;
QAbstractButton *detectedEscapeButton;
QLabel *informativeLabel;
+#ifdef Q_OS_SYMBIAN
+ QTextEdit *textEdit;
+#endif
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
QByteArray signalToDisconnectOnClose;
@@ -2459,10 +2462,24 @@ void QMessageBox::setInformativeText(const QString &text)
#endif
label->setWordWrap(true);
QGridLayout *grid = static_cast<QGridLayout *>(layout());
+#ifdef Q_OS_SYMBIAN
+ label->hide();
+ QTextEdit *textEdit = new QTextEdit(this);
+ textEdit->setReadOnly(true);
+ grid->addWidget(textEdit, 1, 1, 1, 1);
+ d->textEdit = textEdit;
+#else
grid->addWidget(label, 1, 1, 1, 1);
+#endif
d->informativeLabel = label;
}
d->informativeLabel->setText(text);
+
+#ifdef Q_OS_SYMBIAN
+ //We need to put the informative label inside textEdit to enable scrolling of long texts.
+ d->textEdit->setText(d->informativeLabel->text());
+#endif
+
d->updateSize();
}
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index 239e29c..a523bab 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -160,6 +160,10 @@ QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
/*!
Returns the bounding rectangle of the source mapped to the given \a system.
+ Calling this function with Qt::DeviceCoordinates outside of
+ QGraphicsEffect::draw() will give undefined results, as there is no device
+ context available.
+
\sa draw()
*/
QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
@@ -309,7 +313,10 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
// Shortcut, no cache for childless pixmap items...
const QGraphicsItem *item = graphicsItem();
if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
- return ((QGraphicsPixmapItem *) item)->pixmap();
+ const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
+ if (offset)
+ *offset = pixmapItem->offset().toPoint();
+ return pixmapItem->pixmap();
}
if (system == Qt::DeviceCoordinates && item
@@ -348,6 +355,10 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
The returned pixmap is clipped to the current painter's device rectangle when
\a system is Qt::DeviceCoordinates.
+ Calling this function with Qt::DeviceCoordinates outside of
+ QGraphicsEffect::draw() will give undefined results, as there is no device
+ context available.
+
\sa draw(), boundingRect()
*/
QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
@@ -363,10 +374,14 @@ QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
invalidateCache();
}
-void QGraphicsEffectSourcePrivate::invalidateCache(bool effectRectChanged) const
+void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
{
- if (effectRectChanged && m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect)
+ if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
+ && (reason == EffectRectChanged
+ || reason == TransformChanged
+ && m_cachedSystem == Qt::LogicalCoordinates))
return;
+
QPixmapCache::remove(m_cacheKey);
}
@@ -398,8 +413,8 @@ QGraphicsEffect::~QGraphicsEffect()
/*!
Returns the effective bounding rectangle for this effect, i.e., the
- bounding rectangle of the source, adjusted by any margins applied by
- the effect itself.
+ bounding rectangle of the source in device coordinates, adjusted by
+ any margins applied by the effect itself.
\sa boundingRectFor(), updateBoundingRect()
*/
@@ -413,7 +428,7 @@ QRectF QGraphicsEffect::boundingRect() const
/*!
Returns the effective bounding rectangle for this effect, given the
- provided \a rect in the source's coordinate space. When writing
+ provided \a rect in the device coordinates. When writing
you own custom effect, you must call updateBoundingRect() whenever any
parameters are changed that may cause this this function to return a
different value.
@@ -512,7 +527,7 @@ void QGraphicsEffect::updateBoundingRect()
Q_D(QGraphicsEffect);
if (d->source) {
d->source->d_func()->effectBoundingRectChanged();
- d->source->d_func()->invalidateCache(true);
+ d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
}
}
@@ -829,22 +844,19 @@ QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
void QGraphicsBlurEffect::draw(QPainter *painter)
{
Q_D(QGraphicsBlurEffect);
- if (d->filter->radius() <= 0) {
+ if (d->filter->radius() < 1) {
drawSource(painter);
return;
}
PixmapPadMode mode = PadToEffectiveBoundingRect;
if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = PadToTransparentBorder;
+ mode = NoPad;
// Draw pixmap in device coordinates to avoid pixmap scaling.
QPoint offset;
- const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
+ QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
d->filter->draw(painter, offset, pixmap);
- painter->setWorldTransform(restoreTransform);
}
/*!
@@ -1025,7 +1037,7 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter)
PixmapPadMode mode = PadToEffectiveBoundingRect;
if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = PadToTransparentBorder;
+ mode = NoPad;
// Draw pixmap in device coordinates to avoid pixmap scaling.
QPoint offset;
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
index 0011eef..cab7a48 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -108,6 +108,13 @@ public:
, m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
{}
+ enum InvalidateReason
+ {
+ TransformChanged,
+ EffectRectChanged,
+ SourceChanged
+ };
+
virtual ~QGraphicsEffectSourcePrivate();
virtual void detach() = 0;
virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
@@ -121,7 +128,9 @@ public:
virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
virtual void effectBoundingRectChanged() = 0;
- void invalidateCache(bool effectRectChanged = false) const;
+
+ void invalidateCache(InvalidateReason reason = SourceChanged) const;
+ Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp
index cf28dc4..6ee4bfc 100644
--- a/src/gui/egl/qegl.cpp
+++ b/src/gui/egl/qegl.cpp
@@ -429,7 +429,10 @@ QString QEglContext::extensions()
bool QEglContext::hasExtension(const char* extensionName)
{
- return extensions().contains(QLatin1String(extensionName));
+ QList<QByteArray> extensions =
+ QByteArray(reinterpret_cast<const char *>
+ (eglQueryString(QEglContext::defaultDisplay(0), EGL_EXTENSIONS))).split(' ');
+ return extensions.contains(extensionName);
}
QEglContext *QEglContext::currentContext(QEgl::API api)
diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp
index 2d37edb..4d4410a 100644
--- a/src/gui/egl/qeglproperties.cpp
+++ b/src/gui/egl/qeglproperties.cpp
@@ -229,6 +229,15 @@ void QEglProperties::setRenderableType(QEgl::API api)
// reductions in complexity are possible.
bool QEglProperties::reduceConfiguration()
{
+ // EGL chooses configs with the highest color depth over
+ // those with smaller (but faster) lower color depths. One
+ // way around this is to set EGL_BUFFER_SIZE to 16, which
+ // trumps the others. Of course, there may not be a 16-bit
+ // config avaliable, so it's the first restraint we remove.
+ if (value(EGL_BUFFER_SIZE) == 16) {
+ removeValue(EGL_BUFFER_SIZE);
+ return true;
+ }
if (removeValue(EGL_SAMPLE_BUFFERS)) {
removeValue(EGL_SAMPLES);
return true;
diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp
index ae5570f..07bb258 100644
--- a/src/gui/embedded/qscreen_qws.cpp
+++ b/src/gui/embedded/qscreen_qws.cpp
@@ -3150,6 +3150,7 @@ int QScreen::subScreenIndexAt(const QPoint &p) const
#if 0
#ifdef QT_LOADABLE_MODULES
+#include <dlfcn.h>
// ### needs update after driver init changes
diff --git a/src/gui/embedded/qscreen_qws.h b/src/gui/embedded/qscreen_qws.h
index b3246f9..7ab49fb 100644
--- a/src/gui/embedded/qscreen_qws.h
+++ b/src/gui/embedded/qscreen_qws.h
@@ -243,7 +243,9 @@ public:
int totalSize() const { return mapsize; }
QRgb * clut() { return screenclut; }
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numCols() { return screencols; }
+#endif
int colorCount() { return screencols; }
virtual QSize mapToDevice(const QSize &) const;
diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h
index 0a2bf27..076b8fa 100644
--- a/src/gui/graphicsview/qgraph_p.h
+++ b/src/gui/graphicsview/qgraph_p.h
@@ -236,11 +236,13 @@ public:
EdgeData *data = edgeData(v, v1);
bool forward = data->from == v;
if (forward) {
- edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n")
+ edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5,%6,%7]\" color=\"#000000\"] \n")
.arg(v->toString())
.arg(v1->toString())
.arg(data->minSize)
+ .arg(data->minPrefSize)
.arg(data->prefSize)
+ .arg(data->maxPrefSize)
.arg(data->maxSize)
;
}
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index 686096c..f504c54 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -158,7 +158,7 @@ QGraphicsAnchor::~QGraphicsAnchor()
\property QGraphicsAnchor::sizePolicy
\brief the size policy for the QGraphicsAnchor.
- By setting the size policy on an anchor you can configure how the item can resize itself
+ By setting the size policy on an anchor you can configure how the anchor can resize itself
from its preferred spacing. For instance, if the anchor has the size policy
QSizePolicy::Minimum, the spacing is the minimum size of the anchor. However, its size
can grow up to the anchors maximum size. If the default size policy is QSizePolicy::Fixed,
@@ -247,7 +247,7 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout()
/*!
Creates an anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge
- of item \a secondItem. The magnitude of the anchor is picked up from the style. Anchors
+ of item \a secondItem. The spacing of the anchor is picked up from the style. Anchors
between a layout edge and an item edge will have a size of 0.
If there is already an anchor between the edges, the the new anchor will replace the old one.
@@ -321,14 +321,14 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
// Horizontal anchor
Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
- d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
+ if (d->addAnchor(firstItem, firstEdge, secondItem, secondEdge)) {
+ // Vertical anchor
+ firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
+ secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
+ d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
- // Vertical anchor
- firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
- secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
- d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
-
- invalidate();
+ invalidate();
+ }
}
/*!
@@ -351,11 +351,14 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
QGraphicsLayoutItem *secondItem,
Qt::Orientations orientations)
{
+ bool ok = true;
if (orientations & Qt::Horizontal) {
- addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft);
- addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
+ // Currently, if the first is ok, then the rest of the calls should be ok
+ ok = addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft) != 0;
+ if (ok)
+ addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
}
- if (orientations & Qt::Vertical) {
+ if (orientations & Qt::Vertical && ok) {
addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop);
addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom);
}
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index a6f5992..1dc6873 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -49,20 +49,34 @@
#endif
#include "qgraphicsanchorlayout_p.h"
+
#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
+// To ensure that all variables inside the simplex solver are non-negative,
+// we limit the size of anchors in the interval [-limit, limit]. Then before
+// sending them to the simplex solver we add "limit" as an offset, so that
+// they are actually calculated in the interval [0, 2 * limit]
+// To avoid numerical errors in platforms where we use single precision,
+// we use a tighter limit for the variables range.
+const qreal g_offset = (sizeof(qreal) == sizeof(double)) ? QWIDGETSIZE_MAX : QWIDGETSIZE_MAX / 32;
QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
: QObjectPrivate(version), layoutPrivate(0), data(0),
sizePolicy(QSizePolicy::Fixed), preferredSize(0),
- hasSize(true), reversed(false)
+ hasSize(true)
{
}
QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
{
- layoutPrivate->removeAnchor(data->from, data->to);
+ if (data) {
+ // The QGraphicsAnchor was already deleted at this moment. We must clean
+ // the dangling pointer to avoid double deletion in the AnchorData dtor.
+ data->graphicsAnchor = 0;
+
+ layoutPrivate->removeAnchor(data->from, data->to);
+ }
}
void QGraphicsAnchorPrivate::setSizePolicy(QSizePolicy::Policy policy)
@@ -80,27 +94,12 @@ void QGraphicsAnchorPrivate::setSpacing(qreal value)
return;
}
- const qreal rawValue = reversed ? -preferredSize : preferredSize;
- if (hasSize && (rawValue == value))
+ if (hasSize && (preferredSize == value))
return;
// The anchor has an user-defined size
hasSize = true;
-
- // The simplex solver cannot handle negative sizes. To workaround that,
- // if value is less than zero, we reverse the anchor and set the absolute
- // value;
- if (value >= 0) {
- preferredSize = value;
- if (reversed)
- qSwap(data->from, data->to);
- reversed = false;
- } else {
- preferredSize = -value;
- if (!reversed)
- qSwap(data->from, data->to);
- reversed = true;
- }
+ preferredSize = value;
layoutPrivate->q_func()->invalidate();
}
@@ -114,9 +113,6 @@ void QGraphicsAnchorPrivate::unsetSpacing()
// Return to standard direction
hasSize = false;
- if (reversed)
- qSwap(data->from, data->to);
- reversed = false;
layoutPrivate->q_func()->invalidate();
}
@@ -128,14 +124,14 @@ qreal QGraphicsAnchorPrivate::spacing() const
return 0;
}
- return reversed ? -preferredSize : preferredSize;
+ return preferredSize;
}
-static void internalSizeHints(QSizePolicy::Policy policy,
- qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
- qreal *minSize, qreal *prefSize,
- qreal *maxSize)
+static void applySizePolicy(QSizePolicy::Policy policy,
+ qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
+ qreal *minSize, qreal *prefSize,
+ qreal *maxSize)
{
// minSize, prefSize and maxSize are initialized
// with item's preferred Size: this is QSizePolicy::Fixed.
@@ -167,6 +163,18 @@ static void internalSizeHints(QSizePolicy::Policy policy,
*prefSize = prefSizeHint;
}
+AnchorData::~AnchorData()
+{
+ if (graphicsAnchor) {
+ // Remove reference to ourself to avoid double removal in
+ // QGraphicsAnchorPrivate dtor.
+ graphicsAnchor->d_func()->data = 0;
+
+ delete graphicsAnchor;
+ }
+}
+
+
void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
{
QSizePolicy::Policy policy;
@@ -182,6 +190,9 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
maxSize = QWIDGETSIZE_MAX;
if (isCenterAnchor)
maxSize /= 2;
+
+ minPrefSize = prefSize;
+ maxPrefSize = maxSize;
return;
} else {
if (orientation == QGraphicsAnchorLayoutPrivate::Horizontal) {
@@ -206,14 +217,18 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
// It is a user-created anchor, fetch size information from the associated QGraphicsAnchor
Q_ASSERT(graphicsAnchor);
QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func();
+
+ // Policy, min and max sizes are straightforward
policy = anchorPrivate->sizePolicy;
minSizeHint = 0;
+ maxSizeHint = QWIDGETSIZE_MAX;
+
+ // Preferred Size
if (anchorPrivate->hasSize) {
- // One can only configure the preferred size of a normal anchor. Their minimum and
- // maximum "size hints" are always 0 and QWIDGETSIZE_MAX, correspondingly. However,
- // their effective size hints might be narrowed down due to their size policies.
+ // Anchor has user-defined size
prefSizeHint = anchorPrivate->preferredSize;
} else {
+ // Fetch size information from style
const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1);
qreal s = styleInfo->defaultSpacing(orient);
if (s < 0) {
@@ -229,10 +244,14 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
}
prefSizeHint = s;
}
- maxSizeHint = QWIDGETSIZE_MAX;
}
- internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint,
- &minSize, &prefSize, &maxSize);
+
+ // Fill minSize, prefSize and maxSize based on policy and sizeHints
+ applySizePolicy(policy, minSizeHint, prefSizeHint, maxSizeHint,
+ &minSize, &prefSize, &maxSize);
+
+ minPrefSize = prefSize;
+ maxPrefSize = maxSize;
// Set the anchor effective sizes to preferred.
//
@@ -252,13 +271,7 @@ void ParallelAnchorData::updateChildrenSizes()
firstEdge->sizeAtPreferred = sizeAtPreferred;
firstEdge->sizeAtMaximum = sizeAtMaximum;
- // We have the convention that the first children will define the direction of the
- // pararell group. So we can check whether the second edge is "forward" in relation
- // to the group if it have the same direction as the first edge. Note that we don't
- // use 'this->from' because it might be changed by vertex simplification.
- const bool secondForward = (firstEdge->from == secondEdge->from);
-
- if (secondForward) {
+ if (secondForward()) {
secondEdge->sizeAtMinimum = sizeAtMinimum;
secondEdge->sizeAtPreferred = sizeAtPreferred;
secondEdge->sizeAtMaximum = sizeAtMaximum;
@@ -272,21 +285,40 @@ void ParallelAnchorData::updateChildrenSizes()
secondEdge->updateChildrenSizes();
}
-bool ParallelAnchorData::calculateSizeHints()
-{
- // Note that parallel groups can lead to unfeasibility, so during calculation, we can
- // find out one unfeasibility. Because of that this method return boolean. This can't
- // happen in sequential, so there the method is void.
+/*
+ \internal
- // Account for parallel anchors where the second edge is backwards.
- // We rely on the fact that a forward anchor of sizes min, pref, max is equivalent
- // to a backwards anchor of size (-max, -pref, -min)
+ Initialize the parallel anchor size hints using the sizeHint information from
+ its children.
- // Also see comments in updateChildrenSizes().
- const bool secondForward = (firstEdge->from == secondEdge->from);
- const qreal secondMin = secondForward ? secondEdge->minSize : -secondEdge->maxSize;
- const qreal secondPref = secondForward ? secondEdge->prefSize : -secondEdge->prefSize;
- const qreal secondMax = secondForward ? secondEdge->maxSize : -secondEdge->minSize;
+ Note that parallel groups can lead to unfeasibility, so during calculation, we can
+ find out one unfeasibility. Because of that this method return boolean. This can't
+ happen in sequential, so there the method is void.
+ */
+bool ParallelAnchorData::calculateSizeHints()
+{
+ // Normalize second child sizes.
+ // A negative anchor of sizes min, minPref, pref, maxPref and max, is equivalent
+ // to a forward anchor of sizes -max, -maxPref, -pref, -minPref, -min
+ qreal secondMin;
+ qreal secondMinPref;
+ qreal secondPref;
+ qreal secondMaxPref;
+ qreal secondMax;
+
+ if (secondForward()) {
+ secondMin = secondEdge->minSize;
+ secondMinPref = secondEdge->minPrefSize;
+ secondPref = secondEdge->prefSize;
+ secondMaxPref = secondEdge->maxPrefSize;
+ secondMax = secondEdge->maxSize;
+ } else {
+ secondMin = -secondEdge->maxSize;
+ secondMinPref = -secondEdge->maxPrefSize;
+ secondPref = -secondEdge->prefSize;
+ secondMaxPref = -secondEdge->minPrefSize;
+ secondMax = -secondEdge->minSize;
+ }
minSize = qMax(firstEdge->minSize, secondMin);
maxSize = qMin(firstEdge->maxSize, secondMax);
@@ -298,23 +330,72 @@ bool ParallelAnchorData::calculateSizeHints()
return false;
}
- // The equivalent preferred Size of a parallel anchor is calculated as to
- // reduce the deviation from the original preferred sizes _and_ to avoid shrinking
- // items below their preferred sizes, unless strictly needed.
-
- // ### This logic only holds if all anchors in the layout are "well-behaved" in the
- // following terms:
+ // Preferred size calculation
+ // The calculation of preferred size is done as follows:
+ //
+ // 1) Check whether one of the child anchors is the layout structural anchor
+ // If so, we can simply copy the preferred information from the other child,
+ // after bounding it to our minimum and maximum sizes.
+ // If not, then we proceed with the actual calculations.
+ //
+ // 2) The whole algorithm for preferred size calculation is based on the fact
+ // that, if a given anchor cannot remain at its preferred size, it'd rather
+ // grow than shrink.
//
- // - There are no negative-sized anchors
- // - All sequential anchors are composed of children in the same direction as the
- // sequential anchor itself
+ // What happens though is that while this affirmative is true for simple
+ // anchors, it may not be true for sequential anchors that have one or more
+ // reversed anchors inside it. That happens because when a sequential anchor
+ // grows, any reversed anchors inside it may be required to shrink, something
+ // we try to avoid, as said above.
//
- // With these assumptions we can grow a child knowing that no hidden items will
- // have to shrink as the result of that.
- // If any of these does not hold, we have a situation where the ParallelAnchor
- // does not have enough information to calculate its equivalent prefSize.
- prefSize = qMax(firstEdge->prefSize, secondPref);
- prefSize = qMin(prefSize, maxSize);
+ // To overcome this, besides their actual preferred size "prefSize", each anchor
+ // exports what we call "minPrefSize" and "maxPrefSize". These two values define
+ // a surrounding interval where, if required to move, the anchor would rather
+ // remain inside.
+ //
+ // For standard anchors, this area simply represents the region between
+ // prefSize and maxSize, which makes sense since our first affirmation.
+ // For composed anchors, these values are calculated as to reduce the global
+ // "damage", that is, to reduce the total deviation and the total amount of
+ // anchors that had to shrink.
+
+ if (firstEdge->isLayoutAnchor) {
+ prefSize = qBound(minSize, secondPref, maxSize);
+ minPrefSize = qBound(minSize, secondMinPref, maxSize);
+ maxPrefSize = qBound(minSize, secondMaxPref, maxSize);
+ } else if (secondEdge->isLayoutAnchor) {
+ prefSize = qBound(minSize, firstEdge->prefSize, maxSize);
+ minPrefSize = qBound(minSize, firstEdge->minPrefSize, maxSize);
+ maxPrefSize = qBound(minSize, firstEdge->maxPrefSize, maxSize);
+ } else {
+ // Calculate the intersection between the "preferred" regions of each child
+ const qreal lowerBoundary =
+ qBound(minSize, qMax(firstEdge->minPrefSize, secondMinPref), maxSize);
+ const qreal upperBoundary =
+ qBound(minSize, qMin(firstEdge->maxPrefSize, secondMaxPref), maxSize);
+ const qreal prefMean =
+ qBound(minSize, (firstEdge->prefSize + secondPref) / 2, maxSize);
+
+ if (lowerBoundary < upperBoundary) {
+ // If there is an intersection between the two regions, this intersection
+ // will be used as the preferred region of the parallel anchor itself.
+ // The preferred size will be the bounded average between the two preferred
+ // sizes.
+ prefSize = qBound(lowerBoundary, prefMean, upperBoundary);
+ minPrefSize = lowerBoundary;
+ maxPrefSize = upperBoundary;
+ } else {
+ // If there is no intersection, we have to attribute "damage" to at least
+ // one of the children. The minimum total damage is achieved in points
+ // inside the region that extends from (1) the upper boundary of the lower
+ // region to (2) the lower boundary of the upper region.
+ // Then, we expose this region as _our_ preferred region and once again,
+ // use the bounded average as our preferred size.
+ prefSize = qBound(upperBoundary, prefMean, lowerBoundary);
+ minPrefSize = upperBoundary;
+ maxPrefSize = lowerBoundary;
+ }
+ }
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
@@ -332,19 +413,28 @@ bool ParallelAnchorData::calculateSizeHints()
1 is at Maximum
*/
static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min,
- qreal pref, qreal max)
+ qreal minPref, qreal pref,
+ qreal maxPref, qreal max)
{
QGraphicsAnchorLayoutPrivate::Interval interval;
qreal lower;
qreal upper;
- if (value < pref) {
- interval = QGraphicsAnchorLayoutPrivate::MinToPreferred;
+ if (value < minPref) {
+ interval = QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred;
lower = min;
+ upper = minPref;
+ } else if (value < pref) {
+ interval = QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred;
+ lower = minPref;
upper = pref;
- } else {
- interval = QGraphicsAnchorLayoutPrivate::PreferredToMax;
+ } else if (value < maxPref) {
+ interval = QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred;
lower = pref;
+ upper = maxPref;
+ } else {
+ interval = QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum;
+ lower = maxPref;
upper = max;
}
@@ -359,19 +449,26 @@ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal valu
}
static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
- qreal min, qreal pref,
- qreal max)
+ qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max)
{
qreal lower;
qreal upper;
switch (factor.first) {
- case QGraphicsAnchorLayoutPrivate::MinToPreferred:
+ case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred:
lower = min;
+ upper = minPref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred:
+ lower = minPref;
upper = pref;
break;
- case QGraphicsAnchorLayoutPrivate::PreferredToMax:
+ case QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred:
lower = pref;
+ upper = maxPref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum:
+ lower = maxPref;
upper = max;
break;
}
@@ -381,34 +478,43 @@ static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qre
void SequentialAnchorData::updateChildrenSizes()
{
- // ### REMOVE ME
- // ### check whether we are guarantee to get those or we need to warn stuff at this
- // point.
- Q_ASSERT(sizeAtMinimum > minSize || qAbs(sizeAtMinimum - minSize) < 0.00000001);
- Q_ASSERT(sizeAtPreferred > minSize || qAbs(sizeAtPreferred - minSize) < 0.00000001);
- Q_ASSERT(sizeAtMaximum > minSize || qAbs(sizeAtMaximum - minSize) < 0.00000001);
-
- // These may be false if this anchor was in parallel with the layout stucture
- // Q_ASSERT(sizeAtMinimum < maxSize || qAbs(sizeAtMinimum - maxSize) < 0.00000001);
- // Q_ASSERT(sizeAtPreferred < maxSize || qAbs(sizeAtPreferred - maxSize) < 0.00000001);
- // Q_ASSERT(sizeAtMaximum < maxSize || qAbs(sizeAtMaximum - maxSize) < 0.00000001);
-
// Band here refers if the value is in the Minimum To Preferred
// band (the lower band) or the Preferred To Maximum (the upper band).
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
- getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
+ getFactor(sizeAtMinimum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
- getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
+ getFactor(sizeAtPreferred, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
- getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
+ getFactor(sizeAtMaximum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
+
+ // XXX This is not safe if Vertex simplification takes place after the sequential
+ // anchor is created. In that case, "prev" will be a group-vertex, different from
+ // "from" or "to", that _contains_ one of them.
+ AnchorVertex *prev = from;
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *e = m_edges.at(i);
- e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->maxSize);
- e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->maxSize);
- e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->maxSize);
+ const bool edgeIsForward = (e->from == prev);
+ if (edgeIsForward) {
+ e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ prev = e->to;
+ } else {
+ Q_ASSERT(prev == e->to);
+ e->sizeAtMinimum = interpolate(minFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ prev = e->from;
+ }
e->updateChildrenSizes();
}
@@ -419,12 +525,31 @@ void SequentialAnchorData::calculateSizeHints()
minSize = 0;
prefSize = 0;
maxSize = 0;
+ minPrefSize = 0;
+ maxPrefSize = 0;
+
+ AnchorVertex *prev = from;
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *edge = m_edges.at(i);
- minSize += edge->minSize;
- prefSize += edge->prefSize;
- maxSize += edge->maxSize;
+
+ const bool edgeIsForward = (edge->from == prev);
+ if (edgeIsForward) {
+ minSize += edge->minSize;
+ prefSize += edge->prefSize;
+ maxSize += edge->maxSize;
+ minPrefSize += edge->minPrefSize;
+ maxPrefSize += edge->maxPrefSize;
+ prev = edge->to;
+ } else {
+ Q_ASSERT(prev == edge->to);
+ minSize -= edge->maxSize;
+ prefSize -= edge->prefSize;
+ maxSize -= edge->minSize;
+ minPrefSize -= edge->maxPrefSize;
+ maxPrefSize -= edge->minPrefSize;
+ prev = edge->from;
+ }
}
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
@@ -588,16 +713,25 @@ AnchorData *QGraphicsAnchorLayoutPrivate::addAnchorMaybeParallel(AnchorData *new
AnchorData *child = children[i];
QList<QSimplexConstraint *> *childConstraints = childrenConstraints[i];
+ // We need to fix the second child constraints if the parallel group will have the
+ // opposite direction of the second child anchor. For the point of view of external
+ // entities, this anchor was reversed. So if at some point we say that the parallel
+ // has a value of 20, this mean that the second child (when reversed) will be
+ // assigned -20.
+ const bool needsReverse = i == 1 && !parallel->secondForward();
+
if (!child->isCenterAnchor)
continue;
parallel->isCenterAnchor = true;
- for (int i = 0; i < constraints.count(); ++i) {
- QSimplexConstraint *c = constraints[i];
+ for (int j = 0; j < constraints.count(); ++j) {
+ QSimplexConstraint *c = constraints[j];
if (c->variables.contains(child)) {
childConstraints->append(c);
qreal v = c->variables.take(child);
+ if (needsReverse)
+ v *= -1;
c->variables.insert(parallel, v);
}
}
@@ -628,24 +762,10 @@ static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph,
const QVector<AnchorVertex*> &vertices,
AnchorVertex *after)
{
- AnchorData *data = graph->edgeData(before, vertices.first());
- Q_ASSERT(data);
-
- const bool forward = (before == data->from);
- QVector<AnchorVertex *> orderedVertices;
-
- if (forward) {
- orderedVertices = vertices;
- } else {
- qSwap(before, after);
- for (int i = vertices.count() - 1; i >= 0; --i)
- orderedVertices.append(vertices.at(i));
- }
-
#if defined(QT_DEBUG) && 0
QString strVertices;
- for (int i = 0; i < orderedVertices.count(); ++i) {
- strVertices += QString::fromAscii("%1 - ").arg(orderedVertices.at(i)->toString());
+ for (int i = 0; i < vertices.count(); ++i) {
+ strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString());
}
QString strPath = QString::fromAscii("%1 - %2%3").arg(before->toString(), strVertices, after->toString());
qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString()));
@@ -654,15 +774,22 @@ static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph,
AnchorVertex *prev = before;
QVector<AnchorData *> edges;
- for (int i = 0; i <= orderedVertices.count(); ++i) {
- AnchorVertex *next = (i < orderedVertices.count()) ? orderedVertices.at(i) : after;
+ // Take from the graph, the edges that will be simplificated
+ for (int i = 0; i < vertices.count(); ++i) {
+ AnchorVertex *next = vertices.at(i);
AnchorData *ad = graph->takeEdge(prev, next);
Q_ASSERT(ad);
edges.append(ad);
prev = next;
}
- SequentialAnchorData *sequence = new SequentialAnchorData(orderedVertices, edges);
+ // Take the last edge (not covered in the loop above)
+ AnchorData *ad = graph->takeEdge(vertices.last(), after);
+ Q_ASSERT(ad);
+ edges.append(ad);
+
+ // Create sequence
+ SequentialAnchorData *sequence = new SequentialAnchorData(vertices, edges);
sequence->from = before;
sequence->to = after;
@@ -922,7 +1049,6 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation]));
QVector<AnchorVertex*> candidates;
- bool candidatesForward = true;
// Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence)
// and the vertex to be visited.
@@ -938,9 +1064,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
// A vertex can trigger an end of sequence if
// (a) it is a layout vertex, we don't simplify away the layout vertices;
// (b) it does not have exactly 2 adjacents;
- // (c) it will change the direction of the sequence;
- // (d) its next adjacent is already visited (a cycle in the graph);
- // (e) the next anchor is a center anchor.
+ // (c) its next adjacent is already visited (a cycle in the graph).
+ // (d) the next anchor is a center anchor.
const QList<AnchorVertex *> &adjacents = g.adjacentVertices(v);
const bool isLayoutVertex = v->m_item == q;
@@ -955,19 +1080,10 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
endOfSequence = isLayoutVertex || adjacents.count() != 2;
if (!endOfSequence) {
- // If this is the first vertice, determine what is the direction to use for this
- // sequence.
- if (candidates.isEmpty()) {
- const AnchorData *data = g.edgeData(beforeSequence, v);
- Q_ASSERT(data);
- candidatesForward = (beforeSequence == data->from);
- }
-
// This is a tricky part. We peek at the next vertex to find out whether
//
- // - the edge from this vertex to the next vertex has the same direction;
- // - we already visited the next vertex;
- // - the next anchor is a center.
+ // - we already visited the next vertex (c);
+ // - the next anchor is a center (d).
//
// Those are needed to identify the remaining end of sequence cases. Note that unlike
// (a) and (b), we preempt the end of sequence by looking into the next vertex.
@@ -985,22 +1101,17 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
const AnchorData *data = g.edgeData(v, after);
Q_ASSERT(data);
- const bool willChangeDirection = (candidatesForward != (v == data->from));
const bool cycleFound = visited.contains(after);
- // Now cases (c), (d) and (e)...
- endOfSequence = willChangeDirection || cycleFound || data->isCenterAnchor;
+ // Now cases (c) and (d)...
+ endOfSequence = cycleFound || data->isCenterAnchor;
- if (endOfSequence) {
- if (!willChangeDirection) {
- // If the direction will not change, we can add the current vertex to the
- // candidates list and we know that 'after' can be used as afterSequence.
- candidates.append(v);
- afterSequence = after;
- }
- } else {
+ if (!endOfSequence) {
// If it's not an end of sequence, then the vertex didn't trigger neither of the
- // previously four cases, so it can be added to the candidates list.
+ // previously three cases, so it can be added to the candidates list.
+ candidates.append(v);
+ } else if (cycleFound && (beforeSequence != after)) {
+ afterSequence = after;
candidates.append(v);
}
}
@@ -1143,9 +1254,15 @@ void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorDa
c->variables.insert(parallel->firstEdge, v);
}
+ // When restoring, we might have to revert constraints back. See comments on
+ // addAnchorMaybeParallel().
+ const bool needsReverse = !parallel->secondForward();
+
for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) {
QSimplexConstraint *c = parallel->m_secondConstraints.at(i);
qreal v = c->variables[parallel];
+ if (needsReverse)
+ v *= -1;
c->variables.remove(parallel);
c->variables.insert(parallel->secondEdge, v);
}
@@ -1187,7 +1304,22 @@ void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation)
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
QList<AnchorVertexPair *> &toRestore = simplifiedVertices[orientation];
- // We will restore the vertices in the inverse order of creation, this way we ensure that
+ // Since we keep a list of parallel anchors and vertices that were created during vertex
+ // simplification, we can now iterate on those lists instead of traversing the graph
+ // recursively.
+
+ // First, restore the constraints changed when we created parallel anchors. Note that this
+ // works at this point because the constraints doesn't depend on vertex information and at
+ // this point it's always safe to identify whether the second child is forward or backwards.
+ // In the next step, we'll change the anchors vertices so that would not be possible anymore.
+ QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
+
+ for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
+ ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
+ restoreSimplifiedConstraints(parallel);
+ }
+
+ // Then, we will restore the vertices in the inverse order of creation, this way we ensure that
// the vertex being restored was not wrapped by another simplification.
for (int i = toRestore.count() - 1; i >= 0; --i) {
AnchorVertexPair *pair = toRestore.at(i);
@@ -1231,20 +1363,9 @@ void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation)
delete pair;
}
- toRestore.clear();
-
- // The restoration process for vertex simplification also restored the effect of the
- // parallel anchors created during vertex simplification, so we just need to restore
- // the constraints in case of parallels that contain center anchors. For the same
- // reason as above, order matters here.
- QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
-
- for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
- ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
- restoreSimplifiedConstraints(parallel);
- delete parallel;
- }
+ qDeleteAll(parallelAnchors);
parallelAnchors.clear();
+ toRestore.clear();
}
QGraphicsAnchorLayoutPrivate::Orientation
@@ -1545,6 +1666,13 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
return 0;
}
+ const QGraphicsLayoutItem *parentWidget = q->parentLayoutItem();
+ if (firstItem == parentWidget || secondItem == parentWidget) {
+ qWarning("QGraphicsAnchorLayout::addAnchor(): "
+ "You cannot add the parent of the layout to the layout.");
+ return 0;
+ }
+
// In QGraphicsAnchorLayout, items are represented in its internal
// graph as four anchors that connect:
// - Left -> HCenter
@@ -1652,6 +1780,10 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge)
{
+ // Do not expose internal anchors
+ if (firstItem == secondItem)
+ return 0;
+
const Orientation orientation = edgeOrientation(firstEdge);
AnchorVertex *v1 = internalVertex(firstItem, firstEdge);
AnchorVertex *v2 = internalVertex(secondItem, secondEdge);
@@ -1659,8 +1791,16 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi
QGraphicsAnchor *graphicsAnchor = 0;
AnchorData *data = graph[orientation].edgeData(v1, v2);
- if (data)
- graphicsAnchor = acquireGraphicsAnchor(data);
+ if (data) {
+ // We could use "acquireGraphicsAnchor" here, but to avoid a regression where
+ // an internal anchor was wrongly exposed, I want to ensure no new
+ // QGraphicsAnchor instances are created by this call.
+ // This assumption must hold because anchors are either user-created (and already
+ // have their public object created), or they are internal (and must not reach
+ // this point).
+ Q_ASSERT(data->graphicsAnchor);
+ graphicsAnchor = data->graphicsAnchor;
+ }
return graphicsAnchor;
}
@@ -1675,12 +1815,16 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
{
Q_Q(QGraphicsAnchorLayout);
- // Actually delete the anchor
- removeAnchor_helper(firstVertex, secondVertex);
-
+ // Save references to items while it's safe to assume the vertices exist
QGraphicsLayoutItem *firstItem = firstVertex->m_item;
QGraphicsLayoutItem *secondItem = secondVertex->m_item;
+ // Delete the anchor (may trigger deletion of center vertices)
+ removeAnchor_helper(firstVertex, secondVertex);
+
+ // Ensure no dangling pointer is left behind
+ firstVertex = secondVertex = 0;
+
// Checking if the item stays in the layout or not
bool keepFirstItem = false;
bool keepSecondItem = false;
@@ -2047,6 +2191,25 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
/*!
\internal
+ Shift all the constraints by a certain amount. This allows us to deal with negative values in
+ the linear program if they are bounded by a certain limit. Functions should be careful to
+ call it again with a negative amount, to shift the constraints back.
+*/
+static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qreal amount)
+{
+ for (int i = 0; i < constraints.count(); ++i) {
+ QSimplexConstraint *c = constraints.at(i);
+ qreal multiplier = 0;
+ foreach (qreal v, c->variables.values()) {
+ multiplier += v;
+ }
+ c->constant += multiplier * amount;
+ }
+}
+
+/*!
+ \internal
+
Calculate the sizes for all anchors which are part of the trunk. This works
on top of a (possibly) simplified graph.
*/
@@ -2067,12 +2230,14 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints;
+ shiftConstraints(allConstraints, g_offset);
+
// Solve min and max size hints
qreal min, max;
feasible = solveMinMax(allConstraints, path, &min, &max);
if (feasible) {
- solvePreferred(allConstraints, variables);
+ solvePreferred(constraints, variables);
// Calculate and set the preferred size for the layout,
// from the edge sizes that were calculated above.
@@ -2090,6 +2255,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
}
qDeleteAll(sizeHintConstraints);
+ shiftConstraints(constraints, -g_offset);
} else {
// No Simplex is necessary because the path was simplified all the way to a single
@@ -2120,8 +2286,8 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables)
{
- QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
- bool feasible = solvePreferred(constraints + sizeHintConstraints, variables);
+ shiftConstraints(constraints, g_offset);
+ bool feasible = solvePreferred(constraints, variables);
if (feasible) {
// Propagate size at preferred to other sizes. Semi-floats always will be
@@ -2134,7 +2300,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstra
}
}
- qDeleteAll(sizeHintConstraints);
+ shiftConstraints(constraints, -g_offset);
return feasible;
}
@@ -2298,17 +2464,23 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
if (ad->dependency == AnchorData::Slave)
continue;
- if ((ad->minSize == ad->maxSize) || qFuzzyCompare(ad->minSize, ad->maxSize)) {
+ // To use negative variables inside simplex, we shift them so the minimum negative value is
+ // mapped to zero before solving. To make sure that it works, we need to guarantee that the
+ // variables are all inside a certain boundary.
+ qreal boundedMin = qBound(-g_offset, ad->minSize, g_offset);
+ qreal boundedMax = qBound(-g_offset, ad->maxSize, g_offset);
+
+ if ((boundedMin == boundedMax) || qFuzzyCompare(boundedMin, boundedMax)) {
QSimplexConstraint *c = new QSimplexConstraint;
c->variables.insert(ad, 1.0);
- c->constant = ad->minSize;
+ c->constant = boundedMin;
c->ratio = QSimplexConstraint::Equal;
anchorConstraints += c;
unboundedProblem = false;
} else {
QSimplexConstraint *c = new QSimplexConstraint;
c->variables.insert(ad, 1.0);
- c->constant = ad->minSize;
+ c->constant = boundedMin;
c->ratio = QSimplexConstraint::MoreOrEqual;
anchorConstraints += c;
@@ -2320,7 +2492,7 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
c = new QSimplexConstraint;
c->variables.insert(ad, 1.0);
- c->constant = ad->maxSize;
+ c->constant = boundedMax;
c->ratio = QSimplexConstraint::LessOrEqual;
anchorConstraints += c;
unboundedProblem = false;
@@ -2331,7 +2503,8 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
if (unboundedProblem) {
QSimplexConstraint *c = new QSimplexConstraint;
c->variables.insert(layoutEdge, 1.0);
- c->constant = QWIDGETSIZE_MAX;
+ // The maximum size that the layout can take
+ c->constant = g_offset;
c->ratio = QSimplexConstraint::LessOrEqual;
anchorConstraints += c;
}
@@ -2597,6 +2770,8 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
result = getFactor(current,
sizeHints[orientation][Qt::MinimumSize],
sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::PreferredSize],
sizeHints[orientation][Qt::MaximumSize]);
interpolationInterval[orientation] = result.first;
@@ -2625,6 +2800,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorDat
interpolationProgress[orientation]);
qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred,
+ edge->sizeAtPreferred, edge->sizeAtPreferred,
edge->sizeAtMaximum);
Q_ASSERT(edge->from == base || edge->to == base);
@@ -2652,34 +2828,46 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *>
for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter)
objective.variables.insert(*iter, -1.0);
+ const qreal objectiveOffset = (path.positives.count() - path.negatives.count()) * g_offset;
simplex.setObjective(&objective);
// Calculate minimum values
- *min = simplex.solveMin();
+ *min = simplex.solveMin() - objectiveOffset;
// Save sizeAtMinimum results
QList<AnchorData *> variables = getVariables(constraints);
for (int i = 0; i < variables.size(); ++i) {
AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
- ad->sizeAtMinimum = ad->result;
- Q_ASSERT(ad->sizeAtMinimum >= ad->minSize ||
- qAbs(ad->sizeAtMinimum - ad->minSize) < 0.00000001);
+ ad->sizeAtMinimum = ad->result - g_offset;
}
// Calculate maximum values
- *max = simplex.solveMax();
+ *max = simplex.solveMax() - objectiveOffset;
// Save sizeAtMaximum results
for (int i = 0; i < variables.size(); ++i) {
AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
- ad->sizeAtMaximum = ad->result;
- // Q_ASSERT(ad->sizeAtMaximum <= ad->maxSize ||
- // qAbs(ad->sizeAtMaximum - ad->maxSize) < 0.00000001);
+ ad->sizeAtMaximum = ad->result - g_offset;
}
}
return feasible;
}
+enum slackType { Grower = -1, Shrinker = 1 };
+static QPair<QSimplexVariable *, QSimplexConstraint *> createSlack(QSimplexConstraint *sizeConstraint,
+ qreal interval, slackType type)
+{
+ QSimplexVariable *slack = new QSimplexVariable;
+ sizeConstraint->variables.insert(slack, type);
+
+ QSimplexConstraint *limit = new QSimplexConstraint;
+ limit->variables.insert(slack, 1.0);
+ limit->ratio = QSimplexConstraint::LessOrEqual;
+ limit->constant = interval;
+
+ return qMakePair(slack, limit);
+}
+
bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables)
{
@@ -2690,7 +2878,8 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
// Fill the objective coefficients for this variable. In the
// end the objective function will be
//
- // z = n * (A_shrink + B_shrink + ...) + (A_grower + B_grower + ...)
+ // z = n * (A_shrinker_hard + A_grower_hard + B_shrinker_hard + B_grower_hard + ...) +
+ // (A_shrinker_soft + A_grower_soft + B_shrinker_soft + B_grower_soft + ...)
//
// where n is the number of variables that have
// slacks. Note that here we use the number of variables
@@ -2702,7 +2891,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
// and we now fill the values for the slack constraints (one per variable),
// which have this form (the constant A_pref was set when creating the slacks):
//
- // A + A_shrinker - A_grower = A_pref
+ // A + A_shrinker_hard + A_shrinker_soft - A_grower_hard - A_grower_soft = A_pref
//
for (int i = 0; i < variables.size(); ++i) {
AnchorData *ad = variables.at(i);
@@ -2711,22 +2900,58 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
if (ad->isLayoutAnchor)
continue;
- QSimplexVariable *grower = new QSimplexVariable;
- QSimplexVariable *shrinker = new QSimplexVariable;
- QSimplexConstraint *c = new QSimplexConstraint;
- c->variables.insert(ad, 1.0);
- c->variables.insert(shrinker, 1.0);
- c->variables.insert(grower, -1.0);
- c->constant = ad->prefSize;
+ // By default, all variables are equal to their preferred size. If they have room to
+ // grow or shrink, such flexibility will be added by the additional variables below.
+ QSimplexConstraint *sizeConstraint = new QSimplexConstraint;
+ preferredConstraints += sizeConstraint;
+ sizeConstraint->variables.insert(ad, 1.0);
+ sizeConstraint->constant = ad->prefSize + g_offset;
+
+ // Can easily shrink
+ QPair<QSimplexVariable *, QSimplexConstraint *> slack;
+ const qreal softShrinkInterval = ad->prefSize - ad->minPrefSize;
+ if (softShrinkInterval) {
+ slack = createSlack(sizeConstraint, softShrinkInterval, Shrinker);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == 1 (soft)
+ objective.variables.insert(slack.first, 1.0);
+ }
- preferredConstraints += c;
- preferredVariables += grower;
- preferredVariables += shrinker;
+ // Can easily grow
+ const qreal softGrowInterval = ad->maxPrefSize - ad->prefSize;
+ if (softGrowInterval) {
+ slack = createSlack(sizeConstraint, softGrowInterval, Grower);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
- objective.variables.insert(grower, 1.0);
- objective.variables.insert(shrinker, variables.size());
- }
+ // Add to objective with ratio == 1 (soft)
+ objective.variables.insert(slack.first, 1.0);
+ }
+
+ // Can shrink if really necessary
+ const qreal hardShrinkInterval = ad->minPrefSize - ad->minSize;
+ if (hardShrinkInterval) {
+ slack = createSlack(sizeConstraint, hardShrinkInterval, Shrinker);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == N (hard)
+ objective.variables.insert(slack.first, variables.size());
+ }
+ // Can grow if really necessary
+ const qreal hardGrowInterval = ad->maxSize - ad->maxPrefSize;
+ if (hardGrowInterval) {
+ slack = createSlack(sizeConstraint, hardGrowInterval, Grower);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == N (hard)
+ objective.variables.insert(slack.first, variables.size());
+ }
+ }
QSimplex *simplex = new QSimplex;
bool feasible = simplex->setConstraints(constraints + preferredConstraints);
@@ -2739,7 +2964,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
// Save sizeAtPreferred results
for (int i = 0; i < variables.size(); ++i) {
AnchorData *ad = variables.at(i);
- ad->sizeAtPreferred = ad->result;
+ ad->sizeAtPreferred = ad->result - g_offset;
}
// Make sure we delete the simplex solver -before- we delete the
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index 8529e2e..3be9d41 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -123,17 +123,17 @@ struct AnchorData : public QSimplexVariable {
AnchorData()
: QSimplexVariable(), from(0), to(0),
minSize(0), prefSize(0), maxSize(0),
+ minPrefSize(0), maxPrefSize(0),
sizeAtMinimum(0), sizeAtPreferred(0),
sizeAtMaximum(0), item(0), graphicsAnchor(0),
type(Normal), isLayoutAnchor(false),
isCenterAnchor(false), orientation(0),
dependency(Independent) {}
+ virtual ~AnchorData();
virtual void updateChildrenSizes() {}
void refreshSizeHints(const QLayoutStyleInfo *styleInfo = 0);
- virtual ~AnchorData() {}
-
#ifdef QT_DEBUG
void dump(int indent = 2);
inline QString toString() const;
@@ -154,6 +154,9 @@ struct AnchorData : public QSimplexVariable {
qreal prefSize;
qreal maxSize;
+ qreal minPrefSize;
+ qreal maxPrefSize;
+
// Calculated sizes
// These attributes define which sizes should that anchor be in when the
// layout is at its minimum, preferred or maximum sizes. Values are
@@ -213,7 +216,8 @@ struct ParallelAnchorData : public AnchorData
Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
((first->from == second->to) && (first->to == second->from)));
- // We arbitrarily choose the direction of the first child as "our" direction
+ // Our convention will be that the parallel group anchor will have the same
+ // direction as the first anchor.
from = first->from;
to = first->to;
#ifdef QT_DEBUG
@@ -224,6 +228,13 @@ struct ParallelAnchorData : public AnchorData
virtual void updateChildrenSizes();
bool calculateSizeHints();
+ bool secondForward() const {
+ // We have the convention that the first children will define the direction of the
+ // pararell group. Note that we can't rely on 'this->from' or 'this->to' because they
+ // might be changed by vertex simplification.
+ return firstEdge->from == secondEdge->from;
+ }
+
AnchorData* firstEdge;
AnchorData* secondEdge;
@@ -343,7 +354,6 @@ public:
qreal preferredSize;
uint hasSize : 1; // if false, get size from style.
- uint reversed : 1; // if true, the anchor was inverted to keep its value positive
};
@@ -365,8 +375,10 @@ public:
//
// Interval represents which interpolation interval are we operating in.
enum Interval {
- MinToPreferred = 0,
- PreferredToMax
+ MinimumToMinPreferred = 0,
+ MinPreferredToPreferred,
+ PreferredToMaxPreferred,
+ MaxPreferredToMaximum
};
// Several structures internal to the layout are duplicated to handle
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index bb45e7e..726d571 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1341,8 +1341,8 @@ QGraphicsItem::~QGraphicsItem()
}
if (!d_ptr->children.isEmpty()) {
- QList<QGraphicsItem *> oldChildren = d_ptr->children;
- qDeleteAll(oldChildren);
+ while (!d_ptr->children.isEmpty())
+ delete d_ptr->children.first();
Q_ASSERT(d_ptr->children.isEmpty());
}
@@ -2181,7 +2181,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Enable subfocus
- if (newVisible) {
+ if (scene && newVisible) {
QGraphicsItem *p = parent;
bool done = false;
while (p) {
@@ -2554,6 +2554,8 @@ QGraphicsEffect *QGraphicsItem::graphicsEffect() const
If \a effect is the installed on a different item, setGraphicsEffect() will remove
the effect from the item and install it on this item.
+ QGraphicsItem takes ownership of \a effect.
+
\note This function will apply the effect on itself and all its children.
\since 4.6
@@ -2563,38 +2565,54 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
if (d_ptr->graphicsEffect == effect)
return;
- if (d_ptr->graphicsEffect && effect) {
+ if (d_ptr->graphicsEffect) {
delete d_ptr->graphicsEffect;
d_ptr->graphicsEffect = 0;
}
- if (!effect) {
- // Unset current effect.
- QGraphicsEffectPrivate *oldEffectPrivate = d_ptr->graphicsEffect->d_func();
- d_ptr->graphicsEffect = 0;
- if (oldEffectPrivate) {
- oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
- if (d_ptr->scene) { // Update the views directly.
- d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/false,
- /*force=*/false, /*ignoreOpacity=*/false,
- /*removeItemFromScene=*/true);
- }
- }
- } else {
+ if (effect) {
// Set new effect.
QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
d_ptr->graphicsEffect = effect;
effect->d_func()->setGraphicsEffectSource(source);
+ prepareGeometryChange();
}
-
- prepareGeometryChange();
}
#endif //QT_NO_GRAPHICSEFFECT
/*!
\internal
\since 4.6
+ Returns the effective bounding rect of the given item space rect.
+ If the item has no effect, the rect is returned unmodified.
+ If the item has an effect, the effective rect can be extend beyond the
+ item's bounding rect, depending on the effect.
+
+ \sa boundingRect()
+*/
+QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
+{
+#ifndef QT_NO_GRAPHICSEFFECT
+ Q_Q(const QGraphicsItem);
+ QGraphicsEffect *effect = graphicsEffect;
+ if (scene && effect && effect->isEnabled()) {
+ QRectF sceneRect = q->mapRectToScene(rect);
+ QRectF sceneEffectRect;
+ foreach (QGraphicsView *view, scene->views()) {
+ QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
+ QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
+ sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
+ }
+ return q->mapRectFromScene(sceneEffectRect);
+ }
+#endif //QT_NO_GRAPHICSEFFECT
+ return rect;
+}
+
+/*!
+ \internal
+ \since 4.6
Returns the effective bounding rect of the item.
If the item has no effect, this is the same as the item's bounding rect.
If the item has an effect, the effective rect can be larger than the item's
@@ -2605,16 +2623,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
{
#ifndef QT_NO_GRAPHICSEFFECT
- QGraphicsEffect *effect = graphicsEffect;
- QRectF brect = effect && effect->isEnabled() ? effect->boundingRect() : q_ptr->boundingRect();
+ Q_Q(const QGraphicsItem);
+ QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
return brect;
const QGraphicsItem *effectParent = parent;
while (effectParent) {
- effect = effectParent->d_ptr->graphicsEffect;
- if (effect && effect->isEnabled())
- brect = effect->boundingRectFor(brect);
+ QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
+ if (scene && effect && effect->isEnabled()) {
+ const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
+ const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
+ brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
+ }
if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
return brect;
effectParent = effectParent->d_ptr->parent;
@@ -7156,9 +7177,16 @@ void QGraphicsItem::prepareGeometryChange()
QGraphicsItem *parent = this;
while ((parent = parent->d_ptr->parent)) {
- parent->d_ptr->dirtyChildrenBoundingRect = 1;
+ QGraphicsItemPrivate *parentp = parent->d_ptr.data();
+ parentp->dirtyChildrenBoundingRect = 1;
// ### Only do this if the parent's effect applies to the entire subtree.
- parent->d_ptr->notifyBoundingRectChanged = 1;
+ parentp->notifyBoundingRectChanged = 1;
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (parentp->scene && parentp->graphicsEffect) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ }
+#endif
}
}
@@ -7305,13 +7333,6 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
*/
/*!
- \property QGraphicsObject::id
- \brief the id of of the item
-
- \sa QObject::objectName(), QObject::setObjectName()
-*/
-
-/*!
\property QGraphicsObject::opacity
\brief the opacity of the item
@@ -9713,7 +9734,7 @@ void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
}
QWidget *widget = event->widget();
- if (widget) {
+ if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
}
dd->clickCausedFocus = 0;
@@ -10523,6 +10544,20 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
if (!item->pos().isNull())
newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+ // removing additional transformations properties applied with itemTransform()
+ QPointF origin = item->transformOriginPoint();
+ QMatrix4x4 m;
+ QList<QGraphicsTransform*> transformList = item->transformations();
+ for (int i = 0; i < transformList.size(); ++i)
+ transformList.at(i)->applyTo(&m);
+ newItemTransform *= m.toTransform().inverted();
+ newItemTransform.translate(origin.x(), origin.y());
+ newItemTransform.rotate(-item->rotation());
+ newItemTransform.scale(1/item->scale(), 1/item->scale());
+ newItemTransform.translate(-origin.x(), -origin.y());
+
+ // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
+
item->setTransform(newItemTransform);
item->d_func()->setIsMemberOfGroup(true);
prepareGeometryChange();
@@ -10547,11 +10582,39 @@ void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
}
QGraphicsItem *newParent = d_ptr->parent;
+
+ // COMBINE
+ bool ok;
+ QTransform itemTransform;
+ if (newParent)
+ itemTransform = item->itemTransform(newParent, &ok);
+ else
+ itemTransform = item->sceneTransform();
+
QPointF oldPos = item->mapToItem(newParent, 0, 0);
item->setParentItem(newParent);
- // ### This function should remap the item's matrix to keep the item's
- // transformation unchanged relative to the scene.
item->setPos(oldPos);
+
+ // removing position from translation component of the new transform
+ if (!item->pos().isNull())
+ itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+
+ // removing additional transformations properties applied
+ // with itemTransform() or sceneTransform()
+ QPointF origin = item->transformOriginPoint();
+ QMatrix4x4 m;
+ QList<QGraphicsTransform*> transformList = item->transformations();
+ for (int i = 0; i < transformList.size(); ++i)
+ transformList.at(i)->applyTo(&m);
+ itemTransform *= m.toTransform().inverted();
+ itemTransform.translate(origin.x(), origin.y());
+ itemTransform.rotate(-item->rotation());
+ itemTransform.scale(1 / item->scale(), 1 / item->scale());
+ itemTransform.translate(-origin.x(), -origin.y());
+
+ // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
+
+ item->setTransform(itemTransform);
item->d_func()->setIsMemberOfGroup(item->group() != 0);
// ### Quite expensive. But removeFromGroup() isn't called very often.
@@ -10661,26 +10724,45 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
}
-
if (!item->d_ptr->scene)
return QPixmap();
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
const QRectF sourceRect = boundingRect(system);
- QRect effectRect;
+ QRectF effectRectF;
+ bool unpadded = false;
if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
- effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ if (info) {
+ effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates));
+ unpadded = (effectRectF.size() == sourceRect.size());
+ if (info && system == Qt::LogicalCoordinates)
+ effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
+ } else {
+ // no choice but to send a logical coordinate bounding rect to boundingRectFor
+ effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
+ }
} else if (mode == QGraphicsEffect::PadToTransparentBorder) {
// adjust by 1.5 to account for cosmetic pens
- effectRect = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5).toAlignedRect();
+ effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
} else {
- effectRect = sourceRect.toAlignedRect();
+ effectRectF = sourceRect;
+ unpadded = true;
}
+ QRect effectRect = effectRectF.toAlignedRect();
+
if (offset)
*offset = effectRect.topLeft();
+ bool untransformed = !deviceCoordinates
+ || info->painter->worldTransform().type() <= QTransform::TxTranslate;
+ if (untransformed && unpadded && isPixmap()) {
+ if (offset)
+ *offset = boundingRect(system).topLeft().toPoint();
+ return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
+ }
+
if (deviceCoordinates) {
// Clip to viewport rect.
int left, top, right, bottom;
@@ -10708,12 +10790,6 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
if (effectRect.isEmpty())
return QPixmap();
- if (system == Qt::LogicalCoordinates
- && effectRect.size() == sourceRect.size()
- && isPixmap()) {
- return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
- }
-
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
QPainter pixmapPainter(&pixmap);
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 8bbe9f1..8818a0b 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -537,7 +537,6 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
{
Q_OBJECT
Q_PROPERTY(QGraphicsObject * parent READ parentObject WRITE setParentItem NOTIFY parentChanged DESIGNABLE false)
- Q_PROPERTY(QString id READ objectName WRITE setObjectName)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index d6ffb1a..2d8de65 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -236,6 +236,8 @@ public:
QRectF effectiveBoundingRect() const;
QRectF sceneEffectiveBoundingRect() const;
+ QRectF effectiveBoundingRect(const QRectF &rect) const;
+
virtual void resolveFont(uint inheritedMask)
{
for (int i = 0; i < children.size(); ++i)
@@ -562,7 +564,10 @@ public:
{}
inline void detach()
- { item->setGraphicsEffect(0); }
+ {
+ item->d_ptr->graphicsEffect = 0;
+ item->prepareGeometryChange();
+ }
inline const QGraphicsItem *graphicsItem() const
{ return item; }
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp
index 2e9a30c..1e426c8 100644
--- a/src/gui/graphicsview/qgraphicslayout.cpp
+++ b/src/gui/graphicsview/qgraphicslayout.cpp
@@ -148,6 +148,10 @@ QT_BEGIN_NAMESPACE
\a parent is passed to QGraphicsLayoutItem's constructor and the
QGraphicsLayoutItem's isLayout argument is set to \e true.
+
+ If \a parent is a QGraphicsWidget the layout will be installed
+ on that widget. (Note that installing a layout will delete the old one
+ installed.)
*/
QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutItem *parent)
: QGraphicsLayoutItem(*new QGraphicsLayoutPrivate)
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 8777cdc..182a3f5 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -569,14 +569,10 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
item->d_ptr->clearSubFocus();
- if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- widget->d_func()->fixFocusChainBeforeReparenting(0, 0);
- }
-
if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
unregisterScenePosItem(item);
+ QGraphicsScene *oldScene = item->d_func()->scene;
item->d_func()->scene = 0;
//We need to remove all children first because they might use their parent
@@ -587,6 +583,11 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
q->removeItem(item->d_ptr->children.at(i));
}
+ if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
+ }
+
// Unregister focus proxy.
item->d_ptr->resetFocusProxy();
@@ -613,6 +614,19 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
if (item == lastActivePanel)
lastActivePanel = 0;
+ // Cancel active touches
+ {
+ QMap<int, QGraphicsItem *>::iterator it = itemForTouchPointId.begin();
+ while (it != itemForTouchPointId.end()) {
+ if (it.value() == item) {
+ sceneCurrentTouchPoints.remove(it.key());
+ it = itemForTouchPointId.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
// Disable selectionChanged() for individual items
++selectionChanging;
int oldSelectedItemsSize = selectedItems.size();
@@ -4233,7 +4247,6 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &
if (!subPix.isNull()) {
// Blit the subpixmap into the main pixmap.
pixmapPainter.begin(pix);
- pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
pixmapPainter.setClipRegion(pixmapExposed);
pixmapPainter.drawPixmap(br.topLeft(), subPix);
pixmapPainter.end();
@@ -4658,10 +4671,13 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
painter->setWorldTransform(*transformPtr);
painter->setOpacity(opacity);
- if (sourced->lastEffectTransform != painter->worldTransform()) {
+ if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
+ && sourced->lastEffectTransform != painter->worldTransform())
+ {
sourced->lastEffectTransform = painter->worldTransform();
- sourced->invalidateCache();
+ sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
}
+
item->d_ptr->graphicsEffect->draw(painter);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;
@@ -5680,17 +5696,22 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
touchEvent->setAccepted(acceptTouchEvents);
res = acceptTouchEvents && sendEvent(item, touchEvent);
eventAccepted = touchEvent->isAccepted();
- item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
+ if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) {
+ // item was deleted
+ item = 0;
+ } else {
+ item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
+ }
touchEvent->spont = false;
if (res && eventAccepted) {
// the first item to accept the TouchBegin gets an implicit grab.
for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
- itemForTouchPointId[touchPoint.id()] = item;
+ itemForTouchPointId[touchPoint.id()] = item; // can be zero
}
break;
}
- if (item->isPanel())
+ if (item && item->isPanel())
break;
}
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 3f9f443..3bb40fb 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -545,6 +545,32 @@ qint64 QGraphicsViewPrivate::verticalScroll() const
/*!
\internal
+
+ Maps the given rectangle to the scene using QTransform::mapRect()
+*/
+QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
+ return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
+}
+
+
+/*!
+ \internal
+
+ Maps the given rectangle from the scene using QTransform::mapRect()
+*/
+QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
+}
+
+/*!
+ \internal
*/
void QGraphicsViewPrivate::updateScroll()
{
@@ -1182,6 +1208,11 @@ void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
{
Q_D(QGraphicsView);
d->transformationAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->transformationAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
}
/*!
@@ -1209,6 +1240,11 @@ void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
{
Q_D(QGraphicsView);
d->resizeAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->resizeAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
}
/*!
@@ -2571,9 +2607,12 @@ void QGraphicsView::setupViewport(QWidget *widget)
}
// We are only interested in mouse tracking if items
- // accept hover events or use non-default cursors.
- if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
- || !d->scene->d_func()->allItemsUseDefaultCursor)) {
+ // accept hover events or use non-default cursors or if
+ // AnchorUnderMouse is used as transformation or resize anchor.
+ if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
+ || !d->scene->d_func()->allItemsUseDefaultCursor))
+ || d->transformationAnchor == AnchorUnderMouse
+ || d->resizeAnchor == AnchorUnderMouse) {
widget->setMouseTracking(true);
}
diff --git a/src/gui/graphicsview/qgraphicsview.h b/src/gui/graphicsview/qgraphicsview.h
index 2aed0e6..90576e5 100644
--- a/src/gui/graphicsview/qgraphicsview.h
+++ b/src/gui/graphicsview/qgraphicsview.h
@@ -278,6 +278,7 @@ private:
friend class QGraphicsSceneWidget;
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
+ friend class QGraphicsItemPrivate;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::CacheMode)
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index cd161ad..d4b718e 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -86,6 +86,9 @@ public:
qint64 horizontalScroll() const;
qint64 verticalScroll() const;
+ QRectF mapRectToScene(const QRect &rect) const;
+ QRectF mapRectFromScene(const QRectF &rect) const;
+
QPointF mousePressItemPoint;
QPointF mousePressScenePoint;
QPoint mousePressViewPoint;
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index fe569f4..8de81c2 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -1054,7 +1054,7 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
break;
case ItemParentChange: {
QGraphicsItem *parent = qVariantValue<QGraphicsItem *>(value);
- d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast<QGraphicsWidget *>(parent) : 0);
+ d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast<QGraphicsWidget *>(parent) : 0, scene());
// Deliver ParentAboutToChange.
QEvent event(QEvent::ParentAboutToChange);
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index b747a30..5b6490f 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -743,7 +743,7 @@ bool QGraphicsWidgetPrivate::hasDecoration() const
/**
* is called after a reparent has taken place to fix up the focus chain(s)
*/
-void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *newScene)
+void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene)
{
Q_Q(QGraphicsWidget);
@@ -789,7 +789,7 @@ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *new
// update tabFocusFirst for oldScene if the item is going to be removed from oldScene
if (newParent)
newScene = newParent->scene();
- QGraphicsScene *oldScene = q->scene();
+
if (oldScene && newScene != oldScene)
oldScene->d_func()->tabFocusFirst = firstOld;
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
index eb53649..65e6962 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ b/src/gui/graphicsview/qgraphicswidget_p.h
@@ -98,7 +98,7 @@ public:
mutable qreal *margins;
void ensureMargins() const;
- void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *newScene = 0);
+ void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene = 0);
void setLayout_helper(QGraphicsLayout *l);
// Layouts
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp
index f61360a..9497a2f 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/graphicsview/qgridlayoutengine.cpp
@@ -51,6 +51,7 @@
#include "qvarlengtharray.h"
#include <QtDebug>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ static void insertOrRemoveItems(QVector<T> &items, int index, int delta)
static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired)
{
Q_ASSERT(sumDesired != 0.0);
- return desired * ::pow(sumAvailable / sumDesired, desired / sumDesired);
+ return desired * qPow(sumAvailable / sumDesired, desired / sumDesired);
}
static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize)
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h
index a5816d1..2004471 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/gui/graphicsview/qsimplex_p.h
@@ -107,7 +107,7 @@ struct QSimplexConstraint
Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant));
- if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.00000001)
+ if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.0000001)
return true;
switch (ratio) {
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index d8809ef..ce7f450 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -165,12 +165,16 @@ public:
QRect rect() const;
int depth() const;
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numColors() const;
+#endif
int colorCount() const;
QRgb color(int i) const;
void setColor(int i, QRgb c);
+#ifdef QT_DEPRECATED
QT_DEPRECATED void setNumColors(int);
+#endif
void setColorCount(int);
bool allGray() const;
@@ -178,7 +182,9 @@ public:
uchar *bits();
const uchar *bits() const;
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numBytes() const;
+#endif
int byteCount() const;
uchar *scanLine(int);
diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp
index 650075b..2aa61b8 100644
--- a/src/gui/image/qimagepixmapcleanuphooks.cpp
+++ b/src/gui/image/qimagepixmapcleanuphooks.cpp
@@ -93,11 +93,11 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook)
imageHooks.removeAll(hook);
}
-
void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm)
{
- for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks.count(); ++i)
- qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks[i](pm);
+ QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
+ for (int i = 0; i < h->pixmapModificationHooks.count(); ++i)
+ h->pixmapModificationHooks[i](pm);
if (qt_pixmap_cleanup_hook_64)
qt_pixmap_cleanup_hook_64(pm->cacheKey());
@@ -105,8 +105,9 @@ void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm)
void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm)
{
- for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks.count(); ++i)
- qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks[i](pm);
+ QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
+ for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i)
+ h->pixmapDestructionHooks[i](pm);
if (qt_pixmap_cleanup_hook_64)
qt_pixmap_cleanup_hook_64(pm->cacheKey());
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 074f3eb..7580446 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -471,7 +471,6 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq)
handler = 0;
quality = -1;
imageReaderError = QImageReader::UnknownError;
- errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error"));
q = qq;
}
@@ -1214,11 +1213,12 @@ bool QImageReader::jumpToImage(int imageNumber)
}
/*!
- For image formats that support animation, this function returns
- the number of times the animation should loop. Otherwise, it
- returns -1.
+ For image formats that support animation, this function returns the number
+ of times the animation should loop. If this function returns -1, it can
+ either mean the animation should loop forever, or that an error occurred.
+ If an error occurred, canRead() will return false.
- \sa supportsAnimation(), QImageIOHandler::loopCount()
+ \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead()
*/
int QImageReader::loopCount() const
{
@@ -1228,13 +1228,13 @@ int QImageReader::loopCount() const
}
/*!
- For image formats that support animation, this function returns
- the total number of images in the animation.
+ For image formats that support animation, this function returns the total
+ number of images in the animation. If the format does not support
+ animation, 0 is returned.
- Certain animation formats do not support this feature, in which
- case 0 is returned.
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::imageCount()
+ \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead()
*/
int QImageReader::imageCount() const
{
@@ -1244,11 +1244,13 @@ int QImageReader::imageCount() const
}
/*!
- For image formats that support animation, this function returns
- the number of milliseconds to wait until displaying the next frame
- in the animation. Otherwise, 0 is returned.
+ For image formats that support animation, this function returns the number
+ of milliseconds to wait until displaying the next frame in the animation.
+ If the image format doesn't support animation, 0 is returned.
+
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::nextImageDelay()
+ \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead()
*/
int QImageReader::nextImageDelay() const
{
@@ -1258,11 +1260,13 @@ int QImageReader::nextImageDelay() const
}
/*!
- For image formats that support animation, this function returns
- the sequence number of the current frame. Otherwise, -1 is
- returned.
+ For image formats that support animation, this function returns the
+ sequence number of the current frame. If the image format doesn't support
+ animation, 0 is returned.
+
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::currentImageNumber()
+ \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead()
*/
int QImageReader::currentImageNumber() const
{
@@ -1302,6 +1306,8 @@ QImageReader::ImageReaderError QImageReader::error() const
*/
QString QImageReader::errorString() const
{
+ if (d->errorString.isEmpty())
+ return QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error"));
return d->errorString;
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 617cfe5..7e4597e 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -831,14 +831,13 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
if (QPixmapCache::find(key, *this))
return true;
- if (!data)
- data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
-
- if (data->fromFile(fileName, format, flags)) {
+ QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+ if (tmp->fromFile(fileName, format, flags)) {
+ data = tmp;
QPixmapCache::insert(key, *this);
return true;
}
-
+ delete tmp;
return false;
}
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index d95b4ee..e02b0d6 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -185,7 +185,9 @@ public:
const uchar *qwsBits() const;
int qwsBytesPerLine() const;
QRgb *clut() const;
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numCols() const;
+#endif
int colorCount() const;
#elif defined(Q_WS_MAC)
Qt::HANDLE macQDHandle() const;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 1b01e6f..3c1d7e9 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -375,7 +375,7 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
case QPaintDevice::PdmWidthMM:
return qRound(d->width * 25.4 / qt_defaultDpiX());
case QPaintDevice::PdmHeightMM:
- return qRound(d->width * 25.4 / qt_defaultDpiY());
+ return qRound(d->height * 25.4 / qt_defaultDpiY());
case QPaintDevice::PdmNumColors:
return d->colortable.size();
case QPaintDevice::PdmDepth:
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index dc33ade..8194db5 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -235,7 +235,7 @@ static CFbsBitmap* uncompress(CFbsBitmap* bitmap)
QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
bitmapGc->Activate(bitmapDevice);
- bitmapGc->DrawBitmap(TPoint(), bitmap);
+ bitmapGc->BitBlt(TPoint(), bitmap);
delete bitmapGc;
delete bitmapDevice;
@@ -346,8 +346,6 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
cfbsBitmap(0),
- bitmapDevice(0),
- bitmapGc(0),
pengine(0),
bytes(0),
formatLocked(false)
@@ -385,8 +383,6 @@ void QS60PixmapData::resize(int width, int height)
if(cfbsBitmap->SizeInPixels() != newSize) {
cfbsBitmap->Resize(TSize(width, height));
- bitmapDevice->Resize(TSize(width, height));
- bitmapGc->Resized();
if(pengine) {
delete pengine;
pengine = 0;
@@ -397,21 +393,10 @@ void QS60PixmapData::resize(int width, int height)
}
}
-bool QS60PixmapData::initSymbianBitmapContext()
-{
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- return true;
-}
-
void QS60PixmapData::release()
{
if (cfbsBitmap) {
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- delete bitmapGc;
- delete bitmapDevice;
delete cfbsBitmap;
lock.relock();
}
@@ -419,8 +404,6 @@ void QS60PixmapData::release()
delete pengine;
image = QImage();
cfbsBitmap = 0;
- bitmapGc = 0;
- bitmapDevice = 0;
pengine = 0;
bytes = 0;
}
@@ -428,42 +411,52 @@ void QS60PixmapData::release()
/*!
* Takes ownership of bitmap. Used by window surface
*/
-void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap)
+void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat)
{
- cfbsBitmap = bitmap;
- formatLocked = true;
+ Q_ASSERT(bitmap);
- if(!initSymbianBitmapContext()) {
- qWarning("Could not create CBitmapContext");
- release();
- return;
- }
+ release();
+
+ cfbsBitmap = bitmap;
+ formatLocked = lockFormat;
- setSerialNumber(cfbsBitmap->Handle());
+ setSerialNumber(cfbsBitmap->Handle());
- UPDATE_BUFFER();
+ UPDATE_BUFFER();
- // Create default palette if needed
- if (cfbsBitmap->DisplayMode() == EGray2) {
- image.setColorCount(2);
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
+ // Create default palette if needed
+ if (cfbsBitmap->DisplayMode() == EGray2) {
+ image.setColorCount(2);
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
//Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
//So invert mono bitmaps so that masks work correctly.
image.invertPixels();
- } else if (cfbsBitmap->DisplayMode() == EGray256) {
- for (int i=0; i < 256; ++i)
- image.setColor(i, qRgb(i, i, i));
- }else if (cfbsBitmap->DisplayMode() == EColor256) {
- const TColor256Util *palette = TColor256Util::Default();
- for (int i=0; i < 256; ++i)
- image.setColor(i, (QRgb)(palette->Color256(i).Value()));
- }
+ } else if (cfbsBitmap->DisplayMode() == EGray256) {
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, qRgb(i, i, i));
+ } else if (cfbsBitmap->DisplayMode() == EColor256) {
+ const TColor256Util *palette = TColor256Util::Default();
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, (QRgb)(palette->Color256(i).Value()));
+ }
+}
+
+QImage QS60PixmapData::toImage(const QRect &r) const
+{
+ QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
+ that->beginDataAccess();
+ QImage copy = that->image.copy(r);
+ that->endDataAccess();
+
+ return copy;
}
void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
{
+ release();
+
QImage sourceImage;
if (pixelType() == BitmapType) {
@@ -517,8 +510,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
}
cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
- if (!(cfbsBitmap && initSymbianBitmapContext())) {
- qWarning("Could not create CFbsBitmap and/or CBitmapContext");
+ if (!cfbsBitmap) {
+ qWarning("Could not create CFbsBitmap");
release();
return;
}
@@ -544,17 +537,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
{
- if (data->pixelType() == BitmapType) {
- QBitmap::fromImage(data->toImage().copy(rect));
- return;
- }
-
const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data);
-
- resize(rect.width(), rect.height());
- cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode());
-
- bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect));
+ fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither);
}
bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
@@ -661,12 +645,7 @@ void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel)
QImage QS60PixmapData::toImage() const
{
- QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
- that->beginDataAccess();
- QImage copy = that->image.copy();
- that->endDataAccess();
-
- return copy;
+ return toImage(QRect());
}
QPaintEngine* QS60PixmapData::paintEngine() const
@@ -820,7 +799,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
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.
+ beginDataAccess();
image.invertPixels();
+ endDataAccess();
needsCopy = true;
}
@@ -828,7 +809,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
QImage source;
if (convertToArgb32) {
+ beginDataAccess();
source = image.convertToFormat(QImage::Format_ARGB32);
+ endDataAccess();
displayMode = EColor16MA;
} else {
source = image;
@@ -858,7 +841,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
if(displayMode == EGray2) {
// restore pixels
+ beginDataAccess();
image.invertPixels();
+ endDataAccess();
}
return reinterpret_cast<void*>(bitmap);
diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h
index 8631ebd..2d93622 100644
--- a/src/gui/image/qpixmap_s60_p.h
+++ b/src/gui/image/qpixmap_s60_p.h
@@ -109,14 +109,12 @@ public:
private:
void release();
- void fromSymbianBitmap(CFbsBitmap* bitmap);
- bool initSymbianBitmapContext();
+ void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false);
+ QImage toImage(const QRect &r) const;
QSymbianBitmapDataAccess *symbianBitmapDataAccess;
CFbsBitmap *cfbsBitmap;
- CFbsBitmapDevice *bitmapDevice;
- CFbsBitGc *bitmapGc;
QPaintEngine *pengine;
uchar* bytes;
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index b0b7d72..b7b29d7 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -424,6 +424,11 @@ QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key)
Q_GLOBAL_STATIC(QPMCache, pm_cache)
+int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize()
+{
+ return pm_cache()->size();
+}
+
QPixmapCacheEntry::~QPixmapCacheEntry()
{
pm_cache()->releaseKey(key);
diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
index 3723500..939b86d 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -52,6 +52,10 @@
#include "private/qgraphicssystem_p.h"
#include "private/qpaintengineex_p.h"
#include "private/qpaintengine_raster_p.h"
+#include "qmath.h"
+#include "private/qmath_p.h"
+#include "private/qmemrotate_p.h"
+#include "private/qdrawhelper_p.h"
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
@@ -585,106 +589,338 @@ QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
return d->hints;
}
+const qreal radiusScale = qreal(2.5);
+
/*!
\internal
*/
QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
- const qreal delta = d->radius + 1;
+ const qreal delta = radiusScale * d->radius + 1;
return rect.adjusted(-delta, -delta, delta, delta);
}
-// Blur the image according to the blur radius
-// Based on exponential blur algorithm by Jani Huhtanen
-// (maximum radius is set to 16)
-static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
+template <int shift>
+inline int qt_static_shift(int value)
{
- int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
- int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
+ if (shift == 0)
+ return value;
+ else if (shift > 0)
+ return value << (uint(shift) & 0x1f);
+ else
+ return value >> (uint(-shift) & 0x1f);
+}
- QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- int r1 = rect.top();
- int r2 = rect.bottom();
- int c1 = rect.left();
- int c2 = rect.right();
+template<int aprec, int zprec>
+inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
+{
+ QRgb *pixel = (QRgb *)bptr;
+
+#define Z_MASK (0xff << zprec)
+ const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;
+ const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;
+ const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;
+ const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;
+#undef Z_MASK
+
+ const int zR_zprec = zR >> aprec;
+ const int zG_zprec = zG >> aprec;
+ const int zB_zprec = zB >> aprec;
+ const int zA_zprec = zA >> aprec;
+
+ zR += alpha * (R_zprec - zR_zprec);
+ zG += alpha * (G_zprec - zG_zprec);
+ zB += alpha * (B_zprec - zB_zprec);
+ zA += alpha * (A_zprec - zA_zprec);
+
+#define ZA_MASK (0xff << (zprec + aprec))
+ *pixel =
+ qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)
+ | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)
+ | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)
+ | qt_static_shift<-zprec - aprec>(zB & ZA_MASK);
+#undef ZA_MASK
+}
- int bpl = result.bytesPerLine();
- int rgba[4];
- unsigned char* p;
+const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
- int i1 = 0;
- int i2 = 3;
+template<int aprec, int zprec>
+inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
+{
+ const int A_zprec = int(*(bptr)) << zprec;
+ const int z_zprec = z >> aprec;
+ z += alpha * (A_zprec - z_zprec);
+ *(bptr) = z >> (zprec + aprec);
+}
- if (alphaOnly)
- i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
+template<int aprec, int zprec, bool alphaOnly>
+inline void qt_blurrow(QImage & im, int line, int alpha)
+{
+ uchar *bptr = im.scanLine(line);
+
+ int zR = 0, zG = 0, zB = 0, zA = 0;
+
+ if (alphaOnly && im.format() != QImage::Format_Indexed8)
+ bptr += alphaIndex;
+
+ const int stride = im.depth() >> 3;
+ const int im_width = im.width();
+ for (int index = 0; index < im_width; ++index) {
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ bptr += stride;
+ }
+
+ bptr -= stride;
+
+ for (int index = im_width - 2; index >= 0; --index) {
+ bptr -= stride;
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ }
+}
+
+/*
+* expblur(QImage &img, int radius)
+*
+* Based on exponential blur algorithm by Jani Huhtanen
+*
+* In-place blur of image 'img' with kernel
+* of approximate radius 'radius'.
+*
+* Blurs with two sided exponential impulse
+* response.
+*
+* aprec = precision of alpha parameter
+* in fixed-point format 0.aprec
+*
+* zprec = precision of state parameters
+* zR,zG,zB and zA in fp format 8.zprec
+*/
+template <int aprec, int zprec, bool alphaOnly>
+void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)
+{
+ // halve the radius if we're using two passes
+ if (improvedQuality)
+ radius *= qreal(0.5);
+
+ Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
+ || img.format() == QImage::Format_RGB32);
+
+ // choose the alpha such that pixels at radius distance from a fully
+ // saturated pixel will have an alpha component of no greater than
+ // the cutOffIntensity
+ const qreal cutOffIntensity = 2;
+ int alpha = radius <= qreal(1e-5)
+ ? ((1 << aprec)-1)
+ : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
+
+ int img_height = img.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= improvedQuality; ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
+ }
+
+ QImage temp(img.height(), img.width(), img.format());
+ if (transposed >= 0) {
+ if (img.depth() == 8) {
+ qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ } else {
+ if (img.depth() == 8) {
+ qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ }
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r1) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ img_height = temp.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= improvedQuality; ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
+ }
- p += bpl;
- for (int j = r1; j < r2; j++, p += bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ if (transposed == 0) {
+ qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),
+ temp.width(), temp.height(), temp.bytesPerLine(),
+ reinterpret_cast<quint32*>(img.bits()),
+ img.bytesPerLine());
+ } else {
+ img = temp;
}
+}
+#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
+#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c1 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source)
+{
+ QImage srcImage = source;
+
+ if (source.format() == QImage::Format_Indexed8) {
+ // assumes grayscale
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
+ *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
+ }
+
+ return dest;
+ } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
+ // alpha
+ q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));
+ // rgb
+ const quint16 p16_1 = (p1[2] << 8) | p1[1];
+ const quint16 p16_2 = (p1[5] << 8) | p1[4];
+ const quint16 p16_3 = (p2[2] << 8) | p2[1];
+ const quint16 p16_4 = (p2[5] << 8) | p2[4];
+ const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));
+ q[1] = result & 0xff;
+ q[2] = result >> 8;
+ }
+ }
- p += 4;
- for (int j = c1; j < c2; j++, p += 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ return dest;
+ } else if (source.format() != QImage::Format_ARGB32_Premultiplied
+ && source.format() != QImage::Format_RGB32)
+ {
+ srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r2) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine() >> 2;
+ int sx2 = sx << 1;
+
+ quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
+ int dx = dest.bytesPerLine() >> 2;
+ int ww = dest.width();
+ int hh = dest.height();
- p -= bpl;
- for (int j = r1; j < r2; j++, p -= bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const quint32 *p1 = src;
+ const quint32 *p2 = src + sx;
+ quint32 *q = dst;
+ for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
+ *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
}
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c2 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ return dest;
+}
- p -= 4;
- for (int j = c1; j < c2; j++, p -= 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+Q_GUI_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0)
+{
+ if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
+ && blurImage.format() != QImage::Format_RGB32)
+ {
+ blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
- return result;
+ qreal scale = 1;
+ if (radius >= 4) {
+ blurImage = qt_halfScaled(blurImage);
+ scale = 2;
+ radius *= qreal(0.5);
+ }
+
+ if (alphaOnly)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
+
+ if (p) {
+ p->scale(scale, scale);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);
+ }
+}
+
+Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0)
+{
+ if (blurImage.format() == QImage::Format_Indexed8)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
}
+bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+
/*!
\internal
*/
-void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect) const
+void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
if (!painter->isActive())
return;
- if (d->radius <= 0) {
+ QRectF srcRect = rect;
+ if (srcRect.isNull())
+ srcRect = src.rect();
+
+ if (d->radius <= 1) {
painter->drawPixmap(srcRect.translated(p), src, srcRect);
return;
}
+ qreal scaledRadius = radiusScale * d->radius;
+ qreal scale;
+ if (qt_scaleForTransform(painter->transform(), &scale))
+ scaledRadius /= scale;
+
QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter);
if (blurFilter) {
- blurFilter->setRadius(d->radius);
+ blurFilter->setRadius(scaledRadius);
blurFilter->setBlurHints(d->hints);
blurFilter->draw(painter, p, src, srcRect);
return;
@@ -693,17 +929,17 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
QImage srcImage;
QImage destImage;
- if (srcRect.isNull()) {
+ if (srcRect == src.rect()) {
srcImage = src.toImage();
- destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
-
srcImage = src.copy(rect).toImage();
- destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
}
- painter->drawImage(p, destImage);
+ QTransform transform = painter->worldTransform();
+ painter->translate(p);
+ qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);
+ painter->setWorldTransform(transform);
}
// grayscales the image to dest (could be same). If rect isn't defined
@@ -1095,7 +1331,13 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
tmpPainter.end();
// blur the alpha channel
- tmp = blurred(tmp, tmp.rect(), qRound(d->radius), true);
+ QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
+ blurred.fill(0);
+ QPainter blurPainter(&blurred);
+ qt_blurImage(&blurPainter, tmp, d->radius, false, true);
+ blurPainter.end();
+
+ tmp = blurred;
// blacken the image...
tmpPainter.begin(&tmp);
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 14c863b..1de0f32 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -67,6 +67,9 @@ QT_BEGIN_NAMESPACE
# define Q_INTERNAL_WIN_NO_THROW
#endif
+// avoid going through QImage::scanLine() which calls detach
+#define FAST_SCAN_LINE(data, bpl, y) (data + (y) * bpl)
+
/*
All PNG files load to the minimal QImage equivalent.
@@ -510,7 +513,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
&& outImage->format() == QImage::Format_Indexed8) {
int color_table_size = outImage->colorCount();
for (int y=0; y<(int)height; ++y) {
- uchar *p = outImage->scanLine(y);
+ uchar *p = FAST_SCAN_LINE(data, bpl, y);
uchar *end = p + width;
while (p < end) {
if (*p >= color_table_size)
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 8ec9efb..f2d51f7 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -264,7 +264,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
bool gray = format == "pgm";
if (format == "pbm") {
- image = image.convertToFormat(QImage::Format_MonoLSB);
+ image = image.convertToFormat(QImage::Format_Mono);
} else if (image.depth() == 1) {
image = image.convertToFormat(QImage::Format_Indexed8);
} else {
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index bdff5e7..1bf7662 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -139,8 +139,7 @@ void QCoeFepInputContext::widgetDestroyed(QWidget *w)
// Make sure that the input capabilities of whatever new widget got focused are queried.
CCoeControl *ctrl = w->effectiveWinId();
if (ctrl->IsFocused()) {
- ctrl->SetFocus(false);
- ctrl->SetFocus(true);
+ queueInputCapabilitiesChanged();
}
}
@@ -437,6 +436,10 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes)
{
TCharFormat cFormat;
+ QColor styleTextColor = QApplication::palette("QLineEdit").text().color();
+ TLogicalRgb tontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
+ cFormat.iFontPresentation.iTextColor = tontColor;
+
TInt numChars = 0;
TInt charPos = 0;
int oldSize = attributes->size();
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index acfeff8..f447989 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -70,6 +70,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
itemDelegate(0),
selectionModel(0),
ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
+ noSelectionOnMousePress(false),
selectionMode(QAbstractItemView::ExtendedSelection),
selectionBehavior(QAbstractItemView::SelectItems),
currentlyCommittingEditor(0),
@@ -1622,10 +1623,11 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
d->pressedIndex = index;
d->pressedModifiers = event->modifiers();
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
if ((command & QItemSelectionModel::Current) == 0)
d->pressedPosition = pos + offset;
- else if (!indexAt(d->pressedPosition).isValid())
+ else if (!indexAt(d->pressedPosition - offset).isValid())
d->pressedPosition = visualRect(currentIndex()).center() + offset;
if (edit(index, NoEditTriggers, event))
@@ -1760,9 +1762,10 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
- //in the case the user presses on no item we might decide to clear the selection
- if (d->selectionModel && !index.isValid())
- d->selectionModel->select(QModelIndex(), selectionCommand(index, event));
+ if (d->selectionModel && d->noSelectionOnMousePress) {
+ d->noSelectionOnMousePress = false;
+ d->selectionModel->select(index, selectionCommand(index, event));
+ }
setState(NoState);
@@ -2065,9 +2068,13 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
{
Q_D(QAbstractItemView);
QAbstractScrollArea::focusInEvent(event);
- if (selectionModel()
+
+ const QItemSelectionModel* model = selectionModel();
+ const bool currentIndexValid = currentIndex().isValid();
+
+ if (model
&& !d->currentIndexSet
- && !currentIndex().isValid()) {
+ && !currentIndexValid) {
bool autoScroll = d->autoScroll;
d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
@@ -2075,6 +2082,17 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
d->autoScroll = autoScroll;
}
+
+ if (model && currentIndexValid) {
+ if (currentIndex().flags() != Qt::ItemIsEditable)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+ else
+ setAttribute(Qt::WA_InputMethodEnabled);
+ }
+
+ if (!currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+
d->viewport->update();
}
@@ -2195,7 +2213,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
// note that we don't check if the new current index is enabled because moveCursor() makes sure it is
if (command & QItemSelectionModel::Current) {
d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate);
- if (!indexAt(d->pressedPosition).isValid())
+ if (!indexAt(d->pressedPosition - d->offset()).isValid())
d->pressedPosition = visualRect(oldCurrent).center() + d->offset();
QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center());
setSelection(rect, command);
@@ -2867,6 +2885,8 @@ int QAbstractItemView::sizeHintForRow(int row) const
if (row < 0 || row >= d->model->rowCount() || !model())
return -1;
+ ensurePolished();
+
QStyleOptionViewItemV4 option = d->viewOptionsV4();
int height = 0;
int colCount = d->model->columnCount(d->root);
@@ -2896,6 +2916,8 @@ int QAbstractItemView::sizeHintForColumn(int column) const
if (column < 0 || column >= d->model->columnCount() || !model())
return -1;
+ ensurePolished();
+
QStyleOptionViewItemV4 option = d->viewOptionsV4();
int width = 0;
int rows = d->model->rowCount(d->root);
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 0b5cfbe..7fc6780 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -347,6 +347,7 @@ public:
QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
QPointer<QItemSelectionModel> selectionModel;
QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
+ bool noSelectionOnMousePress;
QAbstractItemView::SelectionMode selectionMode;
QAbstractItemView::SelectionBehavior selectionBehavior;
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp
index 5dd1d76..0ce0e5e 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/gui/itemviews/qlistwidget.cpp
@@ -173,10 +173,11 @@ void QListModel::move(int srcRow, int dstRow)
{
if (srcRow == dstRow
|| srcRow < 0 || srcRow >= items.count()
- || dstRow < 0 || dstRow >= items.count())
+ || dstRow < 0 || dstRow > items.count())
return;
- beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow);
+ if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
+ return;
if (srcRow < dstRow)
--dstRow;
items.move(srcRow, dstRow);
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index fc82f30..646a3a1 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -734,6 +734,33 @@ void QSortFilterProxyModelPrivate::source_items_inserted(
}
}
+ if (model->rowCount(source_parent) == delta_item_count) {
+ // Items were inserted where there were none before.
+ // If it was new rows make sure to create mappings for columns so that a
+ // valid mapping can be retreived later and vice-versa.
+
+ QVector<int> &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns;
+ QVector<int> &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns;
+
+ if (orthogonal_source_to_proxy.isEmpty()) {
+ const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent);
+
+ for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) {
+ if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent)
+ : q->filterAcceptsColumn(ortho_item, source_parent)) {
+ orthogonal_proxy_to_source.append(ortho_item);
+ }
+ }
+ orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size());
+
+ if (orient == Qt::Horizontal) {
+ // We're reacting to columnsInserted, but we've just inserted new rows. Sort them.
+ sort_source_rows(orthogonal_proxy_to_source, source_parent);
+ }
+ build_source_to_proxy_mapping(orthogonal_proxy_to_source, orthogonal_source_to_proxy);
+ }
+ }
+
// Sort and insert the items
if (orient == Qt::Vertical) // Only sort rows
sort_source_rows(source_items, source_parent);
@@ -1171,9 +1198,10 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged()
{
Q_Q(QSortFilterProxyModel);
saved_persistent_indexes.clear();
+ emit q->layoutAboutToBeChanged();
if (persistent.indexes.isEmpty())
return;
- emit q->layoutAboutToBeChanged();
+
saved_persistent_indexes = store_persistent_indexes();
}
@@ -1181,7 +1209,8 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged()
{
Q_Q(QSortFilterProxyModel);
if (saved_persistent_indexes.isEmpty()) {
- q->invalidate();
+ clear_mapping();
+ emit q->layoutChanged();
return;
}
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 3ad9fbb..bcf9cfb 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -2774,6 +2774,7 @@ int QTreeView::sizeHintForColumn(int column) const
d->executePostedLayout();
if (d->viewItems.isEmpty())
return -1;
+ ensurePolished();
int w = 0;
QStyleOptionViewItemV4 option = d->viewOptionsV4();
const QVector<QTreeViewItem> viewItems = d->viewItems;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 7d0e5c7..f2bd288 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -206,7 +206,8 @@ embedded {
qcocoaapplication_mac_p.h \
qcocoaapplicationdelegate_mac_p.h \
qmacgesturerecognizer_mac_p.h \
- qmultitouch_mac_p.h
+ qmultitouch_mac_p.h \
+ qcocoasharedwindowmethods_mac_p.h
OBJECTIVE_SOURCES += \
kernel/qcursor_mac.mm \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 9f4cd0c..4165c95 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -2096,7 +2096,11 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
if (prev) {
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled()) {
- if (prev->hasEditFocus() && reason != Qt::PopupFocusReason)
+ if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ && reason != Qt::ActiveWindowFocusReason
+#endif
+ )
prev->setEditFocus(false);
}
#endif
@@ -3629,12 +3633,46 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// walk through parents and check for gestures
if (qt_gestureManager) {
- if (receiver->isWidgetType()) {
- if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
- return true;
- } else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
- if (qt_gestureManager->filterEvent(gesture, e))
- return true;
+ switch (e->type()) {
+ case QEvent::Paint:
+ case QEvent::MetaCall:
+ case QEvent::DeferredDelete:
+ case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
+ case QEvent::Drop: case QEvent::DragResponse:
+ case QEvent::ChildAdded: case QEvent::ChildPolished:
+#ifdef QT3_SUPPORT
+ case QEvent::ChildInsertedRequest:
+ case QEvent::ChildInserted:
+ case QEvent::LayoutHint:
+#endif
+ case QEvent::ChildRemoved:
+ case QEvent::UpdateRequest:
+ case QEvent::UpdateLater:
+ case QEvent::AccessibilityPrepare:
+ case QEvent::LocaleChange:
+ case QEvent::Style:
+ case QEvent::IconDrag:
+ case QEvent::StyleChange:
+ case QEvent::AccessibilityHelp:
+ case QEvent::AccessibilityDescription:
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop:
+ case QEvent::DynamicPropertyChange:
+ case QEvent::NetworkReplyUpdated:
+ break;
+ default:
+ if (receiver->isWidgetType()) {
+ if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else {
+ // a special case for events that go to QGesture objects.
+ // We pass the object to the gesture manager and it'll figure
+ // out if it's QGesture or not.
+ if (qt_gestureManager->filterEvent(receiver, e))
+ return true;
+ }
}
}
@@ -4092,9 +4130,15 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
touchEvent->setWidget(widget);
touchEvent->setAccepted(acceptTouchEvents);
+ QWeakPointer<QWidget> p = widget;
res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
eventAccepted = touchEvent->isAccepted();
- widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+ if (p.isNull()) {
+ // widget was deleted
+ widget = 0;
+ } else {
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+ }
touchEvent->spont = false;
if (res && eventAccepted) {
// the first widget to accept the TouchBegin gets an implicit grab.
@@ -4103,7 +4147,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->widgetForTouchPointId[touchPoint.id()] = widget;
}
break;
- } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
+ } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
break;
}
QPoint offset = widget->pos();
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 22a0959..688e51f 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1687,7 +1687,10 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
UInt32 mac_buttons = 0;
GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
sizeof(mac_buttons), 0, &mac_buttons);
- buttons = qt_mac_get_buttons(mac_buttons);
+ if (ekind != kEventMouseWheelMoved)
+ buttons = qt_mac_get_buttons(mac_buttons);
+ else
+ buttons = QApplication::mouseButtons();
}
int wheel_deltaX = 0;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index ab57c32..27f2644 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -361,6 +361,8 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
SetFocusing(true);
m_longTapDetector = QLongTapTimer::NewL(this);
+
+ DrawableWindow()->SetPointerGrab(ETrue);
}
}
@@ -472,41 +474,6 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
}
-typedef QPair<QWidget*,QMouseEvent> Event;
-
-/*
- * Helper function called by HandlePointerEvent - separated to keep that function readable
- */
-static void generateEnterLeaveEvents(QList<Event> &events, QWidget *widgetUnderPointer,
- QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
-{
- //moved to another widget, create enter and leave events
- if (S60->lastPointerEventTarget) {
- QMouseEvent mEventLeave(QEvent::Leave, S60->lastPointerEventTarget->mapFromGlobal(
- S60->lastCursorPos), S60->lastCursorPos, button, QApplicationPrivate::mouse_buttons,
- modifiers);
- events.append(Event(S60->lastPointerEventTarget, mEventLeave));
- }
- if (widgetUnderPointer) {
- QMouseEvent mEventEnter(QEvent::Enter, widgetUnderPointer->mapFromGlobal(globalPos),
- globalPos, button, QApplicationPrivate::mouse_buttons, modifiers);
-
- events.append(Event(widgetUnderPointer, mEventEnter));
-#ifndef QT_NO_CURSOR
- S60->curWin = widgetUnderPointer->effectiveWinId();
- if (!QApplication::overrideCursor()) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_set_pointer_sprite(widgetUnderPointer->cursor());
- else
-#endif
- qt_symbian_setWindowCursor(widgetUnderPointer->cursor(), S60->curWin);
- }
-#endif
- }
-}
-
-
void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
{
QMouseEvent::Type type;
@@ -514,85 +481,77 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- if (type == QMouseEvent::None)
- return;
-
- // store events for later sending/saving
- QList<Event > events;
-
QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
+ S60->lastCursorPos = globalPos;
+ S60->lastPointerEventPos = widgetPos;
- // widgets interested in the event
- QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
- if (!widgetUnderPointer)
- widgetUnderPointer = qwidget; //i.e. this container widget
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
- QWidget *widgetWithMouseGrab = QWidget::mouseGrabber();
+ QWidget *popupWidget = qApp->activePopupWidget();
+ QWidget *popupReceiver = 0;
+ if (popupWidget) {
+ QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos));
+ popupReceiver = popupChild ? popupChild : popupWidget;
+ }
- // handle auto grab of pointer when pressing / releasing
- if (!widgetWithMouseGrab && type == QEvent::MouseButtonPress) {
- //if previously auto-grabbed, generate a fake mouse release (platform bug: mouse release event was lost)
- if (S60->mousePressTarget) {
- QMouseEvent mEvent(QEvent::MouseButtonRelease, S60->mousePressTarget->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, modifiers);
- events.append(Event(S60->mousePressTarget,mEvent));
+ if (mouseGrabber) {
+ if (popupReceiver) {
+ sendMouseEvent(popupReceiver, type, globalPos, button, modifiers);
+ } else {
+ sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers);
}
- //auto grab the mouse
- widgetWithMouseGrab = S60->mousePressTarget = widgetUnderPointer;
- widgetWithMouseGrab->grabMouse();
- }
- if (widgetWithMouseGrab && widgetWithMouseGrab == S60->mousePressTarget && type == QEvent::MouseButtonRelease) {
- //release the auto grab - note this release event still goes to the autograb widget
- S60->mousePressTarget = 0;
- widgetWithMouseGrab->releaseMouse();
+ // No Enter/Leave events in grabbing mode.
+ return;
}
- QWidget *widgetToReceiveMouseEvent;
- if (widgetWithMouseGrab)
- widgetToReceiveMouseEvent = widgetWithMouseGrab;
- else
- widgetToReceiveMouseEvent = widgetUnderPointer;
-
- //queue QEvent::Enter and QEvent::Leave, if the pointer has moved
- if (widgetUnderPointer != S60->lastPointerEventTarget && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove))
- generateEnterLeaveEvents(events, widgetUnderPointer, globalPos, button, modifiers);
+ QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
+ if (!widgetUnderPointer)
+ widgetUnderPointer = qwidget;
- //save global state
- S60->lastCursorPos = globalPos;
- S60->lastPointerEventPos = widgetPos;
+ QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget);
S60->lastPointerEventTarget = widgetUnderPointer;
+ QWidget *receiver;
+ if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) {
+ receiver = S60->mousePressTarget;
+ if (type == QEvent::MouseButtonRelease)
+ S60->mousePressTarget = 0;
+ } else {
+ receiver = popupReceiver ? popupReceiver : widgetUnderPointer;
+ if (type == QEvent::MouseButtonPress)
+ S60->mousePressTarget = receiver;
+ }
+
#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
if (S60->brokenPointerCursors)
qt_symbian_move_cursor_sprite();
#endif
- //queue this event.
- Q_ASSERT(widgetToReceiveMouseEvent);
- QMouseEvent mEvent(type, widgetToReceiveMouseEvent->mapFromGlobal(globalPos), globalPos,
+ sendMouseEvent(receiver, type, globalPos, button, modifiers);
+}
+
+void QSymbianControl::sendMouseEvent(
+ QWidget *receiver,
+ QEvent::Type type,
+ const QPoint &globalPos,
+ Qt::MouseButton button,
+ Qt::KeyboardModifiers modifiers)
+{
+ Q_ASSERT(receiver);
+ QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos,
button, QApplicationPrivate::mouse_buttons, modifiers);
- events.append(Event(widgetToReceiveMouseEvent,mEvent));
QEventDispatcherS60 *dispatcher;
// It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widgetToReceiveMouseEvent->d_func()->threadData->eventDispatcher)) != 0) {
+ if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(receiver->d_func()->threadData->eventDispatcher)) != 0) {
if (dispatcher->excludeUserInputEvents()) {
- for (int i=0;i < events.count();++i)
- {
- Event next = events[i];
- dispatcher->saveInputEvent(this, next.first, new QMouseEvent(next.second));
- }
+ dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent));
return;
}
}
- //send events in the queue
- for (int i=0;i < events.count();++i)
- {
- Event next = events[i];
- sendMouseEvent(next.first, &(next.second));
- }
+ sendMouseEvent(receiver, &mEvent);
}
bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
@@ -672,27 +631,58 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
fakeEvent.iType = TPointerEvent::EButton1Up;
S60->virtualMouseAccel = 1;
S60->virtualMouseLastKey = 0;
+ switch (keyCode) {
+ case Qt::Key_Left:
+ S60->virtualMousePressedKeys &= ~QS60Data::Left;
+ break;
+ case Qt::Key_Right:
+ S60->virtualMousePressedKeys &= ~QS60Data::Right;
+ break;
+ case Qt::Key_Up:
+ S60->virtualMousePressedKeys &= ~QS60Data::Up;
+ break;
+ case Qt::Key_Down:
+ S60->virtualMousePressedKeys &= ~QS60Data::Down;
+ break;
+ case Qt::Key_Select:
+ S60->virtualMousePressedKeys &= ~QS60Data::Select;
+ break;
+ }
}
else if (type == EEventKey) {
switch (keyCode) {
case Qt::Key_Left:
+ S60->virtualMousePressedKeys |= QS60Data::Left;
x -= S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Right:
+ S60->virtualMousePressedKeys |= QS60Data::Right;
x += S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Up:
+ S60->virtualMousePressedKeys |= QS60Data::Up;
y -= S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Down:
+ S60->virtualMousePressedKeys |= QS60Data::Down;
y += S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Select:
- fakeEvent.iType = TPointerEvent::EButton1Down;
+ // Platform bug. If you start pressing several keys simultaneously (for
+ // example for drag'n'drop), Symbian starts producing spurious up and
+ // down messages for some keys. Therefore, make sure we have a clean slate
+ // of pressed keys before starting a new button press.
+ if (S60->virtualMousePressedKeys != 0) {
+ S60->virtualMousePressedKeys |= QS60Data::Select;
+ return EKeyWasConsumed;
+ } else {
+ S60->virtualMousePressedKeys |= QS60Data::Select;
+ fakeEvent.iType = TPointerEvent::EButton1Down;
+ }
break;
}
}
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index a26d775..9154284 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -50,152 +50,16 @@
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_BEGIN_NAMESPACE
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
-QT_END_NAMESPACE
QT_USE_NAMESPACE
-
-@interface NSWindow (QtCoverForHackWithCategory)
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-@end
-
-
@implementation QT_MANGLE_NAMESPACE(QCocoaPanel)
-- (BOOL)canBecomeKeyWindow
-{
- QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
-
- bool isToolTip = (widget->windowType() == Qt::ToolTip);
- bool isPopup = (widget->windowType() == Qt::Popup);
- return !(isPopup || isToolTip);
-}
-
/***********************************************************************
- BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel
+ Copy and Paste between QCocoaWindow and QCocoaPanel
This is a bit unfortunate, but thanks to the dynamic dispatch we
have to duplicate this code or resort to really silly forwarding methods
**************************************************************************/
-
-/*
- The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
- get hit. We automatically say we can be first responder if we are a window.
- So, the handling should get handled by the view. This is here more as a
- last resort (i.e., this is code that can potentially be removed).
- */
-
-- (void)toggleToolbarShown:(id)sender
-{
- macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super toggleToolbarShown:sender];
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyDown:theEvent];
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyUp:theEvent];
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent
-{
- qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super flagsChanged:theEvent];
-}
-
-
-- (void)tabletProximity:(NSEvent *)tabletEvent
-{
- qt_dispatchTabletProximityEvent(tabletEvent);
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
- QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
-
- // Cocoa can hold onto the window after we've disavowed its knowledge. So,
- // if we get sent an event afterwards just have it go through the super's
- // version and don't do any stuff with Qt.
- if (!widget) {
- [super sendEvent:event];
- return;
- }
- [self retain];
- QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
- Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
-
- // sometimes need to redirect mouse events to the popup.
- QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != widget) {
- switch([event type])
- {
- case NSLeftMouseDown:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
- // Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
- // (this is standard Qt behavior.)
- break;
- case NSRightMouseDown:
- case NSOtherMouseDown:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton))
- [super sendEvent:event];
- break;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton))
- [super sendEvent:event];
- break;
- case NSMouseMoved:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
- break;
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton))
- [super sendEvent:event];
- break;
- default:
- [super sendEvent:event];
- break;
- }
- } else {
- [super sendEvent:event];
- }
- qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
-
-
- [self release];
-}
-
-- (BOOL)makeFirstResponder:(NSResponder *)responder
-{
- // For some reason Cocoa wants to flip the first responder
- // when Qt doesn't want to, sorry, but "No" :-)
- if (responder == nil && qApp->focusWidget())
- return NO;
- return [super makeFirstResponder:responder];
-}
-
-/***********************************************************************
- END Copy and Paste between QCocoaWindow and QCocoaPanel
-***********************************************************************/
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
-{
- if (styleMask & QtMacCustomizeWindow)
- return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
- return [super frameViewClassForStyleMask:styleMask];
-}
+#include "qcocoasharedwindowmethods_mac_p.h"
@end
#endif
diff --git a/src/gui/kernel/qcocoapanel_mac_p.h b/src/gui/kernel/qcocoapanel_mac_p.h
index d95cd93..69dca1e 100644
--- a/src/gui/kernel/qcocoapanel_mac_p.h
+++ b/src/gui/kernel/qcocoapanel_mac_p.h
@@ -54,12 +54,10 @@
#ifdef QT_MAC_USE_COCOA
#import <Cocoa/Cocoa.h>
-
@interface QT_MANGLE_NAMESPACE(QCocoaPanel) : NSPanel {
bool leftButtonIsRightButton;
}
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-
@end
#endif
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
new file mode 100644
index 0000000..f347240
--- /dev/null
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+/****************************************************************************
+ NB: This is not a header file, dispite the file name suffix. This file is
+ included directly into the source code of qcocoawindow_mac.mm and
+ qcocoapanel_mac.mm to avoid manually doing copy and paste of the exact
+ same code needed at both places. This solution makes it more difficult
+ to e.g fix a bug in qcocoawindow_mac.mm, but forget to do the same in
+ qcocoapanel_mac.mm.
+ The reason we need to do copy and paste in the first place, rather than
+ resolve to method overriding, is that QCocoaPanel needs to inherit from
+ NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
+****************************************************************************/
+
+QT_BEGIN_NAMESPACE
+extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+QT_END_NAMESPACE
+
+- (BOOL)canBecomeKeyWindow
+{
+ QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
+
+ bool isToolTip = (widget->windowType() == Qt::ToolTip);
+ bool isPopup = (widget->windowType() == Qt::Popup);
+ return !(isPopup || isToolTip);
+}
+
+- (void)toggleToolbarShown:(id)sender
+{
+ macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super toggleToolbarShown:sender];
+}
+
+/*
+ The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
+ get hit. We automatically say we can be first responder if we are a window.
+ So, the handling should get handled by the view. This is here more as a
+ last resort (i.e., this is code that can potentially be removed).
+ */
+- (void)keyDown:(NSEvent *)theEvent
+{
+ bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ if (!keyOK)
+ [super keyDown:theEvent];
+}
+
+- (void)keyUp:(NSEvent *)theEvent
+{
+ bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ if (!keyOK)
+ [super keyUp:theEvent];
+}
+
+- (void)flagsChanged:(NSEvent *)theEvent
+{
+ qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super flagsChanged:theEvent];
+}
+
+
+- (void)tabletProximity:(NSEvent *)tabletEvent
+{
+ qt_dispatchTabletProximityEvent(tabletEvent);
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+
+ // Cocoa can hold onto the window after we've disavowed its knowledge. So,
+ // if we get sent an event afterwards just have it go through the super's
+ // version and don't do any stuff with Qt.
+ if (!widget) {
+ [super sendEvent:event];
+ return;
+ }
+
+ [self retain];
+ QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
+ Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
+
+ bool handled = false;
+ // sometimes need to redirect mouse events to the popup.
+ QWidget *popup = qAppInstance()->activePopupWidget();
+ if (popup) {
+ switch([event type])
+ {
+ case NSLeftMouseDown:
+ if (!qt_button_down)
+ qt_button_down = widget;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
+ // Don't call super here. This prevents us from getting the mouseUp event,
+ // which we need to send even if the mouseDown event was not accepted.
+ // (this is standard Qt behavior.)
+ break;
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ if (!qt_button_down)
+ qt_button_down = widget;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
+ break;
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton);
+ qt_button_down = 0;
+ break;
+ case NSMouseMoved:
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
+ break;
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
+ [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
+ handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton);
+ break;
+ default:
+ [super sendEvent:event];
+ break;
+ }
+ } else {
+ [super sendEvent:event];
+ }
+
+ if (!handled)
+ qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
+
+ [self release];
+}
+
+- (BOOL)makeFirstResponder:(NSResponder *)responder
+{
+ // For some reason Cocoa wants to flip the first responder
+ // when Qt doesn't want to, sorry, but "No" :-)
+ if (responder == nil && qApp->focusWidget())
+ return NO;
+ return [super makeFirstResponder:responder];
+}
+
++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
+{
+ if (styleMask & QtMacCustomizeWindow)
+ return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
+ return [super frameViewClassForStyleMask:styleMask];
+}
+
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 3da783f..3352dbd 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -349,7 +349,9 @@ extern "C" {
// since we accepted the drag enter event, the widget expects
// future drage move events.
// ### check if we need to treat this like the drag enter event.
- nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDEEvent.dropAction());
+ nsActions = NSDragOperationNone;
+ // Save as ignored in the answer rect.
+ qDMEvent.setDropAction(Qt::IgnoreAction);
} else {
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
}
@@ -357,7 +359,6 @@ extern "C" {
return nsActions;
}
}
-
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
NSPoint windowPoint = [sender draggingLocation];
@@ -402,13 +403,15 @@ extern "C" {
qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
qDMEvent.accept();
QApplication::sendEvent(qwidget, &qDMEvent);
- qt_mac_copy_answer_rect(qDMEvent);
NSDragOperation operation = qt_mac_mapDropAction(qDMEvent.dropAction());
if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
// ignore this event (we will still receive further notifications)
operation = NSDragOperationNone;
+ // Save as ignored in the answer rect.
+ qDMEvent.setDropAction(Qt::IgnoreAction);
}
+ qt_mac_copy_answer_rect(qDMEvent);
return operation;
}
@@ -708,9 +711,9 @@ extern "C" {
- (void)mouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
+
+ qt_button_down = 0;
}
- (void)rightMouseDown:(NSEvent *)theEvent
@@ -723,9 +726,9 @@ extern "C" {
- (void)rightMouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
+
+ qt_button_down = 0;
}
- (void)otherMouseDown:(NSEvent *)theEvent
@@ -739,10 +742,10 @@ extern "C" {
- (void)otherMouseUp:(NSEvent *)theEvent
{
- qt_button_down = 0;
-
Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, mouseButton);
+
+ qt_button_down = 0;
}
- (void)mouseDragged:(NSEvent *)theEvent
@@ -778,11 +781,18 @@ extern "C" {
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint qlocal = QPoint(localPoint.x, localPoint.y);
- QPoint qglobal = QPoint(globalPoint.x, globalPoint.y);
- Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
+ QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y));
+ Qt::MouseButtons buttons = QApplication::mouseButtons();
bool wheelOK = false;
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
QWidget *widgetToGetMouse = qwidget;
+ // if popup is open it should get wheel events if the cursor is over the popup,
+ // otherwise the event should be ignored.
+ if (QWidget *popup = qAppInstance()->activePopupWidget()) {
+ if (!popup->geometry().contains(qglobal))
+ return;
+ }
+
int deltaX = 0;
int deltaY = 0;
int deltaZ = 0;
@@ -1442,6 +1452,9 @@ Qt::DropAction QDragManager::drag(QDrag *o)
pasteboard:pboard
source:dndParams.view
slideBack:YES];
+ // reset the implicit grab widget when drag ends because we will not
+ // receive the mouse release event when DND is active.
+ qt_button_down = 0;
[dndParams.view release];
[image release];
dragPrivate()->executed_action = Qt::IgnoreAction;
diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm
index 263f0ac..a9aa373 100644
--- a/src/gui/kernel/qcocoawindow_mac.mm
+++ b/src/gui/kernel/qcocoawindow_mac.mm
@@ -50,15 +50,8 @@
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_BEGIN_NAMESPACE
-extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
-QT_END_NAMESPACE
QT_USE_NAMESPACE
-@interface NSWindow (QtCoverForHackWithCategory)
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
-@end
-
@implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration))
- (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget*)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask;
@@ -83,138 +76,12 @@ QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(QCocoaWindow)
-- (BOOL)canBecomeKeyWindow
-{
- return YES;
-}
-
/***********************************************************************
- BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel
+ Copy and Paste between QCocoaWindow and QCocoaPanel
This is a bit unfortunate, but thanks to the dynamic dispatch we
have to duplicate this code or resort to really silly forwarding methods
**************************************************************************/
-
-/*
- The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
- get hit. We automatically say we can be first responder if we are a window.
- So, the handling should get handled by the view. This is here more as a
- last resort (i.e., this is code that can potentially be removed).
- */
-
-- (void)toggleToolbarShown:(id)sender
-{
- macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super toggleToolbarShown:sender];
-}
-
-- (void)keyDown:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyDown:theEvent];
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyUp:theEvent];
-}
-
-- (void)flagsChanged:(NSEvent *)theEvent
-{
- qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- [super flagsChanged:theEvent];
-}
-
-
-- (void)tabletProximity:(NSEvent *)tabletEvent
-{
- qt_dispatchTabletProximityEvent(tabletEvent);
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
- QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
-
- // Cocoa can hold onto the window after we've disavowed its knowledge. So,
- // if we get sent an event afterwards just have it go through the super's
- // version and don't do any stuff with Qt.
- if (!widget) {
- [super sendEvent:event];
- return;
- }
-
- [self retain];
- QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
- Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]);
- // sometimes need to redirect mouse events to the popup.
- QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != widget) {
- switch([event type])
- {
- case NSLeftMouseDown:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton);
- // Don't call super here. This prevents us from getting the mouseUp event,
- // which we need to send even if the mouseDown event was not accepted.
- // (this is standard Qt behavior.)
- break;
- case NSRightMouseDown:
- case NSOtherMouseDown:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton))
- [super sendEvent:event];
- break;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton))
- [super sendEvent:event];
- break;
- case NSMouseMoved:
- qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton);
- break;
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view;
- [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event;
- if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton))
- [super sendEvent:event];
- break;
- default:
- [super sendEvent:event];
- break;
- }
- } else {
- [super sendEvent:event];
- }
- qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton);
-
-
- [self release];
-}
-
-
-- (BOOL)makeFirstResponder:(NSResponder *)responder
-{
- // For some reason Cocoa wants to flip the first responder
- // when Qt doesn't want to, sorry, but "No" :-)
- if (responder == nil && qApp->focusWidget())
- return NO;
- return [super makeFirstResponder:responder];
-}
-
-/***********************************************************************
- END Copy and Paste between QCocoaWindow and QCocoaPanel
-***********************************************************************/
-
-+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
-{
- if (styleMask & QtMacCustomizeWindow)
- return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
- return [super frameViewClassForStyleMask:styleMask];
-}
+#include "qcocoasharedwindowmethods_mac_p.h"
@end
-
#endif
diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h
index a688d96..91c5d4e 100644
--- a/src/gui/kernel/qcocoawindow_mac_p.h
+++ b/src/gui/kernel/qcocoawindow_mac_p.h
@@ -50,13 +50,18 @@
// We mean it.
//
-#include "qmacdefines_mac.h"
#ifdef QT_MAC_USE_COCOA
+#include "qmacdefines_mac.h"
#import <Cocoa/Cocoa.h>
enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by
QT_FORWARD_DECLARE_CLASS(QWidget);
+QT_FORWARD_DECLARE_CLASS(QStringList);
+
+@interface NSWindow (QtCoverForHackWithCategory)
++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
+@end
@interface NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration))
- (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget *)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask;
@@ -70,3 +75,4 @@ QT_FORWARD_DECLARE_CLASS(QWidget);
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
@end
#endif
+
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c4a25e1..eedf0a7 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -409,7 +409,7 @@ QMouseEventEx::~QMouseEventEx()
consider a top-level window A containing a child B which in turn contains a
child C (all with mouse tracking enabled):
- \image hoverEvents.png
+ \image hoverevents.png
Now, if you move the cursor from the top to the bottom in the middle of A,
you will get the following QEvent::MouseMove events:
@@ -432,7 +432,7 @@ QMouseEventEx::~QMouseEventEx()
\o A::HoverMove, B::HoverMove
\o A::HoverMove, B::HoverMove, C::HoverMove
\endlist
-
+
*/
/*!
@@ -3023,7 +3023,7 @@ QShowEvent::~QShowEvent()
This event is only used to notify the application of a request.
It may be safely ignored.
- \note This class is currently supported for Mac Os X only.
+ \note This class is currently supported for Mac OS X only.
*/
/*!
@@ -3066,6 +3066,8 @@ QFileOpenEvent::~QFileOpenEvent()
\fn QUrl QFileOpenEvent::url() const
Returns the url that is being opened.
+
+ \since 4.6
*/
QUrl QFileOpenEvent::url() const
{
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 192f9ac..d7cbebd 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -187,10 +187,8 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
#endif
}
- QList<QGesture *> states =
- m_objectGestures.value(QGestureManager::ObjectGesture(object, type));
// check if the QGesture for this recognizer has already been created
- foreach (QGesture *state, states) {
+ foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
if (m_gestureToRecognizer.value(state) == recognizer)
return state;
}
@@ -215,14 +213,13 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state;
}
-bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
+bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts,
QEvent *event)
{
QSet<QGesture *> triggeredGestures;
QSet<QGesture *> finishedGestures;
QSet<QGesture *> newMaybeGestures;
- QSet<QGesture *> canceledGestures;
QSet<QGesture *> notGestures;
// TODO: sort contexts by the gesture type and check if one of the contexts
@@ -231,7 +228,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
bool ret = false;
// filter the event through recognizers
- typedef QHash<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
Qt::GestureType gestureType = cit.value();
QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
@@ -271,6 +268,9 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
}
}
}
+ if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
+ && newMaybeGestures.isEmpty() && notGestures.isEmpty())
+ return ret;
QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
triggeredGestures &= m_activeGestures;
@@ -280,8 +280,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
// check if a running gesture switched back to not gesture state,
// i.e. were canceled
- QSet<QGesture *> activeToCancelGestures = m_activeGestures & notGestures;
- canceledGestures += activeToCancelGestures;
+ QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
// start timers for new gestures in maybe state
foreach (QGesture *state, newMaybeGestures) {
@@ -449,14 +448,14 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
// return true if accepted (consumed)
bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
{
- QSet<Qt::GestureType> types;
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
QWidget *w = receiver;
typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
if (!w->d_func()->gestureContext.isEmpty()) {
for(ContextIterator it = w->d_func()->gestureContext.begin(),
e = w->d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(w, it.key());
}
}
@@ -468,7 +467,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
e = w->d_func()->gestureContext.end(); it != e; ++it) {
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(w, it.key());
}
}
@@ -477,20 +476,20 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
break;
w = w->parentWidget();
}
- return filterEventThroughContexts(contexts, event);
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
}
#ifndef QT_NO_GRAPHICSVIEW
bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
{
- QSet<Qt::GestureType> types;
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
QGraphicsObject *item = receiver;
if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(item, it.key());
}
}
@@ -503,20 +502,23 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(item, it.key());
}
}
}
item = item->parentObject();
}
- return filterEventThroughContexts(contexts, event);
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
}
#endif
-bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
+bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
{
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
+ return false;
+ QGesture *state = static_cast<QGesture *>(receiver);
+ QMultiMap<QObject *, Qt::GestureType> contexts;
contexts.insert(state, state->gestureType());
return filterEventThroughContexts(contexts, event);
}
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index 4efa10b..5329d1d 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -73,7 +73,7 @@ public:
void unregisterGestureRecognizer(Qt::GestureType type);
bool filterEvent(QWidget *receiver, QEvent *event);
- bool filterEvent(QGesture *receiver, QEvent *event);
+ bool filterEvent(QObject *receiver, QEvent *event);
#ifndef QT_NO_GRAPHICSVIEW
bool filterEvent(QGraphicsObject *receiver, QEvent *event);
#endif //QT_NO_GRAPHICSVIEW
@@ -86,7 +86,7 @@ public:
protected:
void timerEvent(QTimerEvent *event);
- bool filterEventThroughContexts(const QMultiHash<QObject *, Qt::GestureType> &contexts,
+ bool filterEventThroughContexts(const QMultiMap<QObject *, Qt::GestureType> &contexts,
QEvent *event);
private:
diff --git a/src/gui/kernel/qguieventdispatcher_glib.cpp b/src/gui/kernel/qguieventdispatcher_glib.cpp
index f8a638c..a252499 100644
--- a/src/gui/kernel/qguieventdispatcher_glib.cpp
+++ b/src/gui/kernel/qguieventdispatcher_glib.cpp
@@ -152,6 +152,8 @@ static gboolean x11EventSourceDispatch(GSource *s, GSourceFunc callback, gpointe
out:
+ source->d->runTimersOnceWithNormalPriority();
+
if (callback)
callback(user_data);
return true;
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index e3af683..2361dd0 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -282,8 +282,8 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \i SelectPreviousPage \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp
\row \i SelectStartOfLine \i Shift+Home \i Ctrl+Shift+Left \i Shift+Home \i Shift+Home \i Shift+Home
\row \i SelectEndOfLine \i Shift+End \i Ctrl+Shift+Right \i Shift+End \i Shift+End \i Shift+End
- \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up \i (none) \i (none) \i (none)
- \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down \i (none) \i (none) \i (none)
+ \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up, Meta+Shift+A \i (none) \i (none) \i (none)
+ \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down, Meta+Shift+E \i (none) \i (none) \i (none)
\row \i SelectStartOfDocument\i Ctrl+Shift+Home \i Ctrl+Shift+Up, Shift+Home \i Ctrl+Shift+Home\i Ctrl+Shift+Home \i Ctrl+Shift+Home
\row \i SelectEndOfDocument \i Ctrl+Shift+End \i Ctrl+Shift+Down, Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End
\row \i DeleteStartOfWord \i Ctrl+Backspace \i Alt+Backspace \i Ctrl+Backspace \i Ctrl+Backspace \i (none)
@@ -732,6 +732,8 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, QApplicationPrivate::KB_Mac},
{QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, QApplicationPrivate::KB_Mac},
{QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, QApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, QApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, QApplicationPrivate::KB_Mac},
{QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac},
{QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac}
};
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 775d773..0e98f39 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -190,7 +190,7 @@ bool QSoftKeyManager::event(QEvent *e)
}
QWidget *parent = source->parentWidget();
- if (parent && softKeys.isEmpty())
+ if (parent && softKeys.isEmpty() && !source->isWindow())
source = parent;
else
break;
@@ -246,15 +246,22 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
break;
}
- int command = (softKeyAction->objectName().contains("_q_menuSoftKeyAction"))
+ int command = (softKeyAction->objectName().contains(QLatin1String("_q_menuSoftKeyAction")))
? EAknSoftkeyOptions
: s60CommandStart + index;
+ // _q_menuSoftKeyAction action is set to "invisible" and all invisible actions are by default
+ // disabled. However we never want to dim options softkey, even it is set to "invisible"
+ bool dimmed = (command == EAknSoftkeyOptions) ? false : !softKeyAction->isEnabled();
+
if (position != -1) {
const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
QString iconText = softKeyAction->iconText();
TPtrC text = qt_QString2TPtrC( underlineShortCut ? softKeyAction->text() : iconText);
- QT_TRAP_THROWING(nativeContainer->SetCommandL(position, command, text));
+ QT_TRAP_THROWING(
+ nativeContainer->SetCommandL(position, command, text);
+ nativeContainer->DimCommand(command, dimmed);
+ );
}
}
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 2bf1465..ef680a4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -139,6 +139,7 @@ void QMacWindowFader::performFade()
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
extern QWidget * mac_mouse_grabber;
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
{
@@ -748,7 +749,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
NSRect frameRect = [window frame];
if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) {
NSRect contentRect = [window contentRectForFrameRect:frameRect];
- if (fakeNCEvents || !NSMouseInRect(globalPoint, contentRect, NO)) {
+ qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
+ QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint));
+ // check that the mouse pointer is on the non-client area and
+ // there are not widgets in it.
+ if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) {
qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint);
processThisEvent = true;
@@ -759,8 +764,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
// This is not an NC area mouse message.
if (!processThisEvent)
return;
+
// If the window is frame less, generate fake mouse events instead. (floating QToolBar)
- if (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint))
+ // or if someone already got an explicit or implicit grab
+ if (mac_mouse_grabber || qt_button_down ||
+ (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint)))
fakeMouseEvents = true;
Qt::MouseButton button;
@@ -838,8 +846,15 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /*
leftButtonIsRightButton = false;
}
}
+
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods);
qt_sendSpontaneousEvent(widgetToGetEvent, &qme);
+
+ // We don't need to set the implicit grab widget here because we won't
+ // reach this point if then event type is Press over a Qt widget.
+ // However we might need to unset it if the event is Release.
+ if (eventType == QEvent::MouseButtonRelease)
+ qt_button_down = 0;
#endif
}
@@ -873,15 +888,12 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
// Find the widget that *should* get the event (e.g., maybe it was a pop-up,
// they always get the mouse event).
QWidget *qwidget = [theView qt_qwidget];
- QWidget *widgetToGetMouse = qwidget;
+ QWidget *widgetToGetMouse = 0;
+ NSView *tmpView = 0;
QWidget *popup = qAppInstance()->activePopupWidget();
- NSView *tmpView = theView;
- if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetMouse) {
- widgetToGetMouse = mac_mouse_grabber;
- tmpView = qt_mac_nativeview_for(widgetToGetMouse);
- }
+ QPoint qglobalPoint(flipPoint(globalPoint).toPoint());
- if (popup && popup != qwidget->window()) {
+ if (popup) {
widgetToGetMouse = popup;
tmpView = qt_mac_nativeview_for(popup);
windowPoint = [[tmpView window] convertScreenToBase:globalPoint];
@@ -901,13 +913,15 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
}
} else {
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
- if (!mac_mouse_grabber && qt_button_down) {
- // if there is no explicit grabber, and the mouse was grabbed
- // implicitely (i.e. a mousebutton was pressed)
- widgetToGetMouse = qt_button_down;
+ QPoint pos;
+ widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint,
+ pos, eventType,
+ button, qt_button_down, 0);
+ if (widgetToGetMouse)
tmpView = qt_mac_nativeview_for(widgetToGetMouse);
- }
}
+ if (!widgetToGetMouse)
+ return false;
NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil];
QPoint qlocalPoint(localPoint.x, localPoint.y);
@@ -953,14 +967,13 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
break;
}
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint;
- QPoint qglobalPoint(flipPoint(globalPoint).toPoint());
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
}
- return qme.isAccepted();
+ return true;
#endif
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 08f8bb5..737e9d7 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -103,6 +103,14 @@ public:
int defaultDpiY;
WId curWin;
int virtualMouseLastKey;
+ enum PressedKeys {
+ Select = 0x1,
+ Right = 0x2,
+ Down = 0x4,
+ Left = 0x8,
+ Up = 0x10
+ };
+ int virtualMousePressedKeys; // of the above type, but avoids casting problems
int virtualMouseAccel;
int virtualMouseMaxAccel;
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
@@ -192,6 +200,12 @@ private:
TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent);
bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent);
+ void sendMouseEvent(
+ QWidget *receiver,
+ QEvent::Type type,
+ const QPoint &globalPos,
+ Qt::MouseButton button,
+ Qt::KeyboardModifiers modifiers);
void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation );
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index d19c574..81f38ec 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -5046,6 +5046,8 @@ QGraphicsEffect *QWidget::graphicsEffect() const
If \a effect is the installed on a different widget, setGraphicsEffect() will remove
the effect from the widget and install it on this widget.
+ QWidget takes ownership of \a effect.
+
\note This function will apply the effect on itself and all its children.
\since 4.6
@@ -5059,28 +5061,22 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
if (d->graphicsEffect == effect)
return;
- if (d->graphicsEffect && effect) {
+ if (d->graphicsEffect) {
+ d->invalidateBuffer(rect());
delete d->graphicsEffect;
d->graphicsEffect = 0;
}
- if (!effect) {
- // Unset current effect.
- QGraphicsEffectPrivate *oldEffectPrivate = d->graphicsEffect->d_func();
- d->graphicsEffect = 0;
- if (oldEffectPrivate) {
- oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
- }
- } else {
+ if (effect) {
// Set new effect.
QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
d->graphicsEffect = effect;
effect->d_func()->setGraphicsEffectSource(source);
+ update();
}
d->updateIsOpaque();
- update();
}
#endif //QT_NO_GRAPHICSEFFECT
@@ -8380,9 +8376,10 @@ bool QWidget::event(QEvent *event)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
+#ifndef Q_WS_MAC
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
- if (touchPoint.isPrimary())
+ if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad)
break;
// fake a mouse event!
@@ -8411,6 +8408,7 @@ bool QWidget::event(QEvent *event)
Qt::LeftButton,
touchEvent->modifiers());
(void) QApplication::sendEvent(this, &mouseEvent);
+#endif // Q_WS_MAC
break;
}
case QEvent::Gesture:
@@ -9776,13 +9774,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
}
#endif
- if (newParent) {
- if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
+ if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
+ if (newParent)
oldBs->removeDirtyWidget(this);
- // Move the widget and all its static children from
- // the old backing store to the new one.
- oldBs->moveStaticWidgets(this);
- }
+ // Move the widget and all its static children from
+ // the old backing store to the new one.
+ oldBs->moveStaticWidgets(this);
}
if ((QApplicationPrivate::app_compile_version < 0x040200
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 5ba1d23..0824db3 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -744,6 +744,7 @@ private:
friend struct QWidgetExceptionCleaner;
friend class QGestureManager;
friend class QWinNativePanGestureRecognizer;
+ friend class QWidgetEffectSourcePrivate;
#ifdef Q_WS_MAC
friend class QCoreGraphicsPaintEnginePrivate;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 0d9f9ee..0213af9 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2617,8 +2617,6 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
releaseMouse();
if(mac_keyboard_grabber == this)
releaseKeyboard();
- if(acceptDrops())
- setAcceptDrops(false);
if(testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal
QApplicationPrivate::leaveModal(this);
@@ -3656,6 +3654,16 @@ void QWidgetPrivate::setFocus_sys()
}
}
+NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
+{
+ id topView = reinterpret_cast<id>(context);
+ if (view1 == topView)
+ return NSOrderedDescending;
+ if (view2 == topView)
+ return NSOrderedAscending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::raise_sys()
{
Q_Q(QWidget);
@@ -3663,7 +3671,6 @@ void QWidgetPrivate::raise_sys()
return;
#if QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
if (isRealWindow()) {
// Calling orderFront shows the window on Cocoa too.
if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
@@ -3675,16 +3682,9 @@ void QWidgetPrivate::raise_sys()
SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
}
} else {
- // Cocoa doesn't really have an idea of Z-ordering, but you can
- // fake it by changing the order of it. But beware, removing an
- // NSView will also remove it as the first responder. So we re-set
- // the first responder just in case:
NSView *view = qt_mac_nativeview_for(q);
NSView *parentView = [view superview];
- NSResponder *firstResponder = [[view window] firstResponder];
- [view removeFromSuperview];
- [parentView addSubview:view];
- [[view window] makeFirstResponder:firstResponder];
+ [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)];
}
#else
if(q->isWindow()) {
@@ -3702,47 +3702,29 @@ void QWidgetPrivate::raise_sys()
#endif
}
+NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
+{
+ id topView = reinterpret_cast<id>(context);
+ if (view1 == topView)
+ return NSOrderedAscending;
+ if (view2 == topView)
+ return NSOrderedDescending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::lower_sys()
{
Q_Q(QWidget);
if((q->windowType() == Qt::Desktop))
return;
#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
if (isRealWindow()) {
OSWindowRef window = qt_mac_window_for(q);
[window orderBack:window];
} else {
- // Cocoa doesn't really have an idea of Z-ordering, but you can
- // fake it by changing the order of it. In this case
- // we put the item at the beginning of the list, but that means
- // we must re-insert everything since we cannot modify the list directly.
- NSView *myview = qt_mac_nativeview_for(q);
- NSView *parentView = [myview superview];
- NSArray *tmpViews = [parentView subviews];
- NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
- [subviews addObjectsFromArray:tmpViews];
- NSResponder *firstResponder = [[myview window] firstResponder];
- // Implicit assumption that myViewIndex is included in subviews, that's why I'm not checking
- // myViewIndex.
- NSUInteger index = 0;
- NSUInteger myViewIndex = 0;
- bool foundMyView = false;
- for (NSView *subview in subviews) {
- [subview removeFromSuperview];
- if (subview == myview) {
- foundMyView = true;
- myViewIndex = index;
- }
- ++index;
- }
- [parentView addSubview:myview];
- if (foundMyView)
- [subviews removeObjectAtIndex:myViewIndex];
- for (NSView *subview in subviews)
- [parentView addSubview:subview];
- [subviews release];
- [[myview window] makeFirstResponder:firstResponder];
+ NSView *view = qt_mac_nativeview_for(q);
+ NSView *parentView = [view superview];
+ [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)];
}
#else
if(q->isWindow()) {
@@ -3755,6 +3737,16 @@ void QWidgetPrivate::lower_sys()
#endif
}
+NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
+{
+ const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context);
+ if (viewOrder[view1] < viewOrder[view2])
+ return NSOrderedAscending;
+ if (viewOrder[view1] > viewOrder[view2])
+ return NSOrderedDescending;
+ return NSOrderedSame;
+}
+
void QWidgetPrivate::stackUnder_sys(QWidget *w)
{
// stackUnder
@@ -3763,37 +3755,23 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w)
return;
#ifdef QT_MAC_USE_COCOA
// Do the same trick as lower_sys() and put this widget before the widget passed in.
- QMacCocoaAutoReleasePool pool;
- NSView *myview = qt_mac_nativeview_for(q);
+ NSView *myView = qt_mac_nativeview_for(q);
NSView *wView = qt_mac_nativeview_for(w);
- NSView *parentView = [myview superview];
- NSArray *tmpViews = [parentView subviews];
- NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
- [subviews addObjectsFromArray:tmpViews];
- // Implicit assumption that myViewIndex and wViewIndex is included in subviews,
- // that's why I'm not checking myViewIndex.
- NSUInteger index = 0;
- NSUInteger myViewIndex = 0;
- NSUInteger wViewIndex = 0;
- for (NSView *subview in subviews) {
- [subview removeFromSuperview];
- if (subview == myview)
- myViewIndex = index;
- else if (subview == wView)
- wViewIndex = index;
- ++index;
- }
- index = 0;
+ QHash<NSView *, int> viewOrder;
+ NSView *parentView = [myView superview];
+ NSArray *subviews = [parentView subviews];
+ NSUInteger index = 1;
+ // make a hash of view->zorderindex and make sure z-value is always odd,
+ // so that when we modify the order we create a new (even) z-value which
+ // will not interfere with others.
for (NSView *subview in subviews) {
- if (index == myViewIndex)
- continue;
- if (index == wViewIndex)
- [parentView addSubview:myview];
- [parentView addSubview:subview];
+ viewOrder.insert(subview, index * 2);
++index;
}
- [subviews release];
+ viewOrder[myView] = viewOrder[wView] - 1;
+
+ [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)];
#else
QWidget *p = q->parentWidget();
if(!p || p != w->parentWidget())
@@ -4515,10 +4493,14 @@ void QWidgetPrivate::createTLSysExtra()
void QWidgetPrivate::deleteTLSysExtra()
{
#ifndef QT_MAC_USE_COCOA
- if(extra->topextra->group) {
+ if (extra->topextra->group) {
qt_mac_release_window_group(extra->topextra->group);
extra->topextra->group = 0;
}
+ if (extra->topextra->windowIcon) {
+ ReleaseIconRef(extra->topextra->windowIcon);
+ extra->topextra->windowIcon = 0;
+ }
#endif
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 04cf4bb..5d73951 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -823,7 +823,7 @@ public:
{}
inline void detach()
- { m_widget->setGraphicsEffect(0); }
+ { m_widget->d_func()->graphicsEffect = 0; }
inline const QGraphicsItem *graphicsItem() const
{ return 0; }
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 628a109..a6cc9c7 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -379,6 +379,13 @@ symbian {
QMAKE_CXXFLAGS.ARMCC *= -O3
}
+neon {
+ DEFINES += QT_HAVE_NEON
+ HEADERS += painting/qdrawhelper_neon_p.h
+ SOURCES += painting/qdrawhelper_neon.cpp
+ QMAKE_CXXFLAGS *= -mfpu=neon
+}
+
contains(QT_CONFIG, zlib) {
INCLUDEPATH += ../3rdparty/zlib
} else:!contains(QT_CONFIG, no-zlib) {
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index a6b4cef..f626494 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -497,7 +497,7 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o)
cos_a = 1.;
if (cos_a < -1.)
cos_a = -1;
- angles[i] = acos(cos_a)/Q_PI;
+ angles[i] = qAcos(cos_a)/Q_PI;
}
if (angles[0] + angles[1] > 1.) {
@@ -816,17 +816,17 @@ bool QBezier::findIntersections(const QBezier &a, const QBezier &b,
QVector<QPair<qreal, qreal> > *t)
{
if (IntersectBB(a, b)) {
- QPointF la1(fabs((a.x3 - a.x2) - (a.x2 - a.x1)),
- fabs((a.y3 - a.y2) - (a.y2 - a.y1)));
- QPointF la2(fabs((a.x4 - a.x3) - (a.x3 - a.x2)),
- fabs((a.y4 - a.y3) - (a.y3 - a.y2)));
+ QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)),
+ qFabs((a.y3 - a.y2) - (a.y2 - a.y1)));
+ QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)),
+ qFabs((a.y4 - a.y3) - (a.y3 - a.y2)));
QPointF la;
if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x());
if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y());
- QPointF lb1(fabs((b.x3 - b.x2) - (b.x2 - b.x1)),
- fabs((b.y3 - b.y2) - (b.y2 - b.y1)));
- QPointF lb2(fabs((b.x4 - b.x3) - (b.x3 - b.x2)),
- fabs((b.y4 - b.y3) - (b.y3 - b.y2)));
+ QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)),
+ qFabs((b.y3 - b.y2) - (b.y2 - b.y1)));
+ QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)),
+ qFabs((b.y4 - b.y3) - (b.y3 - b.y2)));
QPointF lb;
if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x());
if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y());
@@ -1120,7 +1120,7 @@ static inline void bindInflectionPoint(const QBezier &bez, const qreal t,
qreal ey = 3 * (right.y2 - right.y3);
qreal s4 = qAbs(6 * (ey * ax - ex * ay) / qSqrt(ex * ex + ey * ey)) + 0.00001f;
- qreal tf = pow(qreal(9 * flatness / s4), qreal(1./3.));
+ qreal tf = qPow(qreal(9 * flatness / s4), qreal(1./3.));
*tMinus = t - (1 - t) * tf;
*tPlus = t + (1 - t) * tf;
}
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index 7dbd0c2..c284871 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -166,8 +166,6 @@ inline void QBezier::coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal &
inline QPointF QBezier::pointAt(qreal t) const
{
- Q_ASSERT(t >= 0);
- Q_ASSERT(t <= 1);
#if 1
qreal a, b, c, d;
coefficients(t, a, b, c, d);
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 1d15dac..81d1515 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -605,7 +605,7 @@ static void qt_blend_argb32_on_argb32(uchar *destPixels, int dbpl,
}
-static void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha)
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 4df7f8a..84cf5cc 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -44,6 +44,7 @@
#include <private/qpainter_p.h>
#include <private/qdrawhelper_x86_p.h>
#include <private/qdrawhelper_armv6_p.h>
+#include <private/qdrawhelper_neon_p.h>
#include <private/qmath_p.h>
#include <qmath.h>
@@ -1182,7 +1183,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato
rx -= data->gradient.conical.center.x;
ry -= data->gradient.conical.center.y;
while (buffer < end) {
- qreal angle = atan2(ry, rx) + data->gradient.conical.angle;
+ qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
*buffer = qt_gradient_pixel(&data->gradient, 1 - angle / (2*Q_PI));
@@ -1196,7 +1197,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato
if (!rw)
rw = 1;
while (buffer < end) {
- qreal angle = atan2(ry/rw - data->gradient.conical.center.x,
+ qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
rx/rw - data->gradient.conical.center.y)
+ data->gradient.conical.angle;
@@ -7140,17 +7141,17 @@ void qt_build_pow_tables() {
}
#else
for (int i=0; i<256; ++i) {
- qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255));
- qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255));
+ qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
+ qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
}
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
const qreal gray_gamma = 2.31;
for (int i=0; i<256; ++i)
- qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047));
+ qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
for (int i=0; i<2048; ++i)
- qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255));
+ qt_pow_invgamma[i] = uchar(qRound(qPow(i / 2047.0, 1 / gray_gamma) * 255));
#endif
}
@@ -7725,7 +7726,8 @@ enum CPUFeatures {
SSE = 0x10,
SSE2 = 0x20,
CMOV = 0x40,
- IWMMXT = 0x80
+ IWMMXT = 0x80,
+ NEON = 0x100
};
static uint detectCPUFeatures()
@@ -7751,6 +7753,9 @@ static uint detectCPUFeatures()
// runtime detection only available when running as a previlegied process
static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
return doIWMMXT ? IWMMXT : 0;
+#elif defined(QT_HAVE_NEON)
+ static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
+ return doNEON ? NEON : 0;
#else
uint features = 0;
#if defined(__x86_64__) || defined(Q_OS_WIN64)
@@ -8122,7 +8127,14 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
-#endif // Q_CC_RVCT && QT_HAVE_ARMV6
+#elif defined(QT_HAVE_NEON)
+ if (features & NEON) {
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ }
+#endif
if (functionForModeSolidAsm) {
const int destinationMode = QPainter::CompositionMode_Destination;
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
new file mode 100644
index 0000000..7fe11bf
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $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 <private/qdrawhelper_p.h>
+
+#ifdef QT_HAVE_NEON
+
+#include <private/qdrawhelper_neon_p.h>
+#include <arm_neon.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline int16x8_t qvdiv_255_s16(int16x8_t x, int16x8_t half)
+{
+ // result = (x + (x >> 8) + 0x80) >> 8
+
+ const int16x8_t temp = vshrq_n_s16(x, 8); // x >> 8
+ const int16x8_t sum_part = vaddq_s16(x, half); // x + 0x80
+ const int16x8_t sum = vaddq_s16(temp, sum_part);
+
+ return vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(sum), 8));
+}
+
+static inline int16x8_t qvbyte_mul_s16(int16x8_t x, int16x8_t alpha, int16x8_t half)
+{
+ // t = qRound(x * alpha / 255.0)
+
+ const int16x8_t t = vmulq_s16(x, alpha); // t
+ return qvdiv_255_s16(t, half);
+}
+
+static inline int16x8_t qvinterpolate_pixel_255(int16x8_t x, int16x8_t a, int16x8_t y, int16x8_t b, int16x8_t half)
+{
+ // t = x * a + y * b
+
+ const int16x8_t ta = vmulq_s16(x, a);
+ const int16x8_t tb = vmulq_s16(y, b);
+
+ return qvdiv_255_s16(vaddq_s16(ta, tb), half);
+}
+
+static inline int16x8_t qvsource_over_s16(int16x8_t src16, int16x8_t dst16, int16x8_t half, int16x8_t full)
+{
+ const int16x4_t alpha16_high = vdup_lane_s16(vget_high_s16(src16), 3);
+ const int16x4_t alpha16_low = vdup_lane_s16(vget_low_s16(src16), 3);
+
+ const int16x8_t alpha16 = vsubq_s16(full, vcombine_s16(alpha16_low, alpha16_high));
+
+ return vaddq_s16(src16, qvbyte_mul_s16(dst16, alpha16, half));
+}
+
+void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ const uint *src = (const uint *) srcPixels;
+ uint *dst = (uint *) destPixels;
+ int16x8_t half = vdupq_n_s16(0x80);
+ int16x8_t full = vdupq_n_s16(0xff);
+ if (const_alpha == 256) {
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) {
+ // all opaque
+ vst1q_s32((int32_t *)&dst[x], src32);
+ } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t result16_low = qvsource_over_s16(src16_low, dst16_low, half, full);
+ const int16x8_t result16_high = qvsource_over_s16(src16_high, dst16_high, half, full);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ if (s >= 0xff000000)
+ dst[x] = s;
+ else if (s != 0)
+ dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ } else if (const_alpha != 0) {
+ const_alpha = (const_alpha * 255) >> 8;
+ int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t srcalpha16_low = qvbyte_mul_s16(src16_low, const_alpha16, half);
+ const int16x8_t srcalpha16_high = qvbyte_mul_s16(src16_high, const_alpha16, half);
+
+ const int16x8_t result16_low = qvsource_over_s16(srcalpha16_low, dst16_low, half, full);
+ const int16x8_t result16_high = qvsource_over_s16(srcalpha16_high, dst16_high, half, full);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ if (s != 0) {
+ s = BYTE_MUL(s, const_alpha);
+ dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+ }
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ }
+}
+
+// qblendfunctions.cpp
+void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha != 256) {
+ if (const_alpha != 0) {
+ const uint *src = (const uint *) srcPixels;
+ uint *dst = (uint *) destPixels;
+ int16x8_t half = vdupq_n_s16(0x80);
+ const_alpha = (const_alpha * 255) >> 8;
+ int one_minus_const_alpha = 255 - const_alpha;
+ int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
+ int16x8_t one_minus_const_alpha16 = vdupq_n_s16(255 - const_alpha);
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half);
+ const int16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ s = BYTE_MUL(s, const_alpha);
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ }
+ } else {
+ qt_blend_rgb32_on_rgb32(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_HAVE_NEON
+
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
new file mode 100644
index 0000000..cb9a0d6
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $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 QDRAWHELPER_NEON_P_H
+#define QDRAWHELPER_NEON_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 <private/qdrawhelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_HAVE_NEON
+
+void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+#endif // QT_HAVE_NEON
+
+QT_END_NAMESPACE
+
+#endif // QDRAWHELPER_NEON_P_H
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index 152b3c9..af48bcb 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -102,7 +102,9 @@ public:
bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); }
qreal determinant() const { return _m11*_m22 - _m12*_m21; }
+#ifdef QT_DEPRECATED
QT_DEPRECATED qreal det() const { return _m11*_m22 - _m12*_m21; }
+#endif
QMatrix inverted(bool *invertible = 0) const;
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 67dc2c7..e3a6f78 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -572,5 +572,26 @@ QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
QT_IMPL_MEMROTATE(quint16, qrgb_generic16)
#endif
+struct qrgb_gl_rgba
+{
+public:
+ inline qrgb_gl_rgba(quint32 v) {
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ data = ((v << 16) & 0xff0000) | ((v >> 16) & 0xff) | (v & 0xff00ff00);
+ else
+ data = (v << 8) | ((v >> 24) & 0xff);
+ }
+
+ inline operator quint32() const { return data; }
+
+private:
+ quint32 data;
+} Q_PACKED;
+
+void Q_GUI_EXPORT qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
+ quint32 *dest, int dstStride)
+{
+ qt_memrotate90_template(src, srcWidth, srcHeight, srcStride, reinterpret_cast<qrgb_gl_rgba *>(dest), dstStride);
+}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index 676a880..8aee575 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -81,6 +81,8 @@ QT_BEGIN_NAMESPACE
void Q_GUI_QWS_EXPORT qt_memrotate180(const srctype*, int, int, int, desttype*, int); \
void Q_GUI_QWS_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int)
+void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int);
+
QT_DECL_MEMROTATE(quint32, quint32);
QT_DECL_MEMROTATE(quint32, quint16);
QT_DECL_MEMROTATE(quint16, quint32);
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 9148e4b..0f8191e 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -96,7 +96,9 @@ public:
int logicalDpiY() const { return metric(PdmDpiY); }
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numColors() const { return metric(PdmNumColors); }
+#endif
int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc
index ac1c3de..e923e90 100644
--- a/src/gui/painting/qpaintdevice.qdoc
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -82,7 +82,7 @@
horizontal and vertical resolution of the device in dots per
inch. The physicalDpiX() and physicalDpiY() functions also return
the resolution of the device in dots per inch, but note that if
- the logical and vertical resolution differ, the corresponding
+ the logical and physical resolution differ, the corresponding
QPaintEngine must handle the mapping. Finally, the colorCount()
function returns the number of different colors available for the
paint device.
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 4a72434..aa3b89e 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3018,10 +3018,10 @@ void QRasterPaintEngine::drawCachedGlyphs(const QPointF &p, const QTextItemInt &
QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType;
QImageTextureGlyphCache *cache =
- (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(glyphType, s->matrix);
+ (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(0, glyphType, s->matrix);
if (!cache) {
cache = new QImageTextureGlyphCache(glyphType, s->matrix);
- ti.fontEngine->setGlyphCache(glyphType, cache);
+ ti.fontEngine->setGlyphCache(0, cache);
}
cache->populate(ti, glyphs, positions);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 48629d1..8ed126f 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -284,7 +284,7 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
// Update matrix.
if (q->d_ptr->state->WxF) {
- q->d_ptr->state->redirectionMatrix *= q->d_ptr->state->worldMatrix;
+ q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix;
q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y());
q->d_ptr->state->worldMatrix = QTransform();
q->d_ptr->state->WxF = false;
@@ -1317,6 +1317,90 @@ void QPainterPrivate::updateState(QPainterState *newState)
Another workaround is to convert the paths to polygons first and then draw the
polygons instead.
+ \section1 Performance
+
+ QPainter is a rich framework that allows developers to do a great
+ variety of graphical operations, such as gradients, composition
+ modes and vector graphics. And QPainter can do this across a
+ variety of different hardware and software stacks. Naturally the
+ underlying combination of hardware and software has some
+ implications for performance, and ensuring that every single
+ operation is fast in combination with all the various combinations
+ of composition modes, brushes, clipping, transformation, etc, is
+ close to an impossible task because of the number of
+ permutations. As a compromise we have selected a subset of the
+ QPainter API and backends, were performance is guaranteed to be as
+ good as we can sensibly get it for the given combination of
+ hardware and software.
+
+ The backends we focus on as high-performance engines are:
+
+ \list
+
+ \o Raster - This backend implements all rendering in pure software
+ and is always used to render into QImages. For optimal performance
+ only use the format types QImage::Format_ARGB32_Premultiplied,
+ QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
+ including QImage::Format_ARGB32, has significantly worse
+ performance. This engine is also used by default on Windows and on
+ QWS. It can be used as default graphics system on any
+ OS/hardware/software combination by passing \c {-graphicssystem
+ raster} on the command line
+
+ \o OpenGL 2.0 (ES) - This backend is the primary backend for
+ hardware accelerated graphics. It can be run on desktop machines
+ and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
+ specification. This includes most graphics chips produced in the
+ last couple of years. The engine can be enabled by using QPainter
+ onto a QGLWidget or by passing \c {-graphicssystem opengl} on the
+ command line when the underlying system supports it.
+
+ \o OpenVG - This backend implements the Khronos standard for 2D
+ and Vector Graphics. It is primarily for embedded devices with
+ hardware support for OpenVG. The engine can be enabled by
+ passing \c {-graphicssystem openvg} on the command line when
+ the underlying system supports it.
+
+ \endlist
+
+ These operations are:
+
+ \list
+
+ \o Simple transformations, meaning translation and scaling, pluss
+ 0, 90, 180, 270 degree rotations.
+
+ \o \c drawPixmap() in combination with simple transformations and
+ opacity with non-smooth transformation mode
+ (\c QPainter::SmoothPixmapTransform not enabled as a render hint).
+
+ \o Text drawing with regular font sizes with simple
+ transformations with solid colors using no or 8-bit antialiasing.
+
+ \o Rectangle fills with solid color, two-color linear gradients
+ and simple transforms.
+
+ \o Rectangular clipping with simple transformations and intersect
+ clip.
+
+ \o Composition Modes \c QPainter::CompositionMode_Source and
+ QPainter::CompositionMode_SourceOver
+
+ \o Rounded rectangle filling using solid color and two-color
+ linear gradients fills.
+
+ \o 3x3 patched pixmaps, via qDrawBorderPixmap.
+
+ \endlist
+
+ This list gives an indication of which features to safely use in
+ an application where performance is critical. For certain setups,
+ other operations may be fast too, but before making extensive use
+ of them, it is recommended to benchmark and verify them on the
+ system where the software will run in the end. There are also
+ cases where expensive operations are ok to use, for instance when
+ the result is cached in a QPixmap.
+
\sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
{Drawing Utility Functions}
*/
@@ -5886,7 +5970,12 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption
Draws the text item \a ti at position \a p.
*/
-/*! \internal
+/*!
+ \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
+
+ \internal
+ \since 4.1
+
Draws the text item \a ti at position \a p.
This method ignores the painters background mode and
@@ -5899,34 +5988,57 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption
ignored aswell. You'll need to pass in the correct flags to get
underlining and strikeout.
*/
-static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device)
+
+static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
{
- extern int qt_defaultDpi();
+ const qreal radiusBase = qMax(qreal(1), maxRadius);
+
+ QString key = QLatin1String("WaveUnderline-");
+ key += pen.color().name();
+ key += QLatin1Char('-');
+ key += QString::number(radiusBase);
+
+ QPixmap pixmap;
+ if (QPixmapCache::find(key, pixmap))
+ return pixmap;
+
+ const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
+ const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
+ const int radius = qFloor(radiusBase);
+
QPainterPath path;
- bool up = true;
- const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius));
- qreal xs, ys;
- int i = 0;
- path.moveTo(0, radius);
- do {
- xs = i*(2*radius);
- ys = 0;
+ qreal xs = 0;
+ qreal ys = radius;
- qreal remaining = minWidth - xs;
- qreal angle = 180;
+ while (xs < width) {
+ xs += halfPeriod;
+ ys = -ys;
+ path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
+ }
- // cut-off at the last arc segment
- if (remaining < 2 * radius)
- angle = 180 * remaining / (2 * radius);
+ pixmap = QPixmap(width, radius * 2);
+ pixmap.fill(Qt::transparent);
+ {
+ QPen wavePen = pen;
+ wavePen.setCapStyle(Qt::SquareCap);
+
+ // This is to protect against making the line too fat, as happens on Mac OS X
+ // due to it having a rather thick width for the regular underline.
+ const qreal maxPenWidth = .8 * radius;
+ if (wavePen.widthF() > maxPenWidth)
+ wavePen.setWidth(maxPenWidth);
- path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle);
+ QPainter imgPainter(&pixmap);
+ imgPainter.setPen(wavePen);
+ imgPainter.setRenderHint(QPainter::Antialiasing);
+ imgPainter.translate(0, radius);
+ imgPainter.drawPath(path);
+ }
- up = !up;
- ++i;
- } while (xs + 2*radius < minWidth);
+ QPixmapCache::insert(key, pixmap);
- return path;
+ return pixmap;
}
static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti)
@@ -5947,9 +6059,11 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
pen.setCapStyle(Qt::FlatCap);
QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y());
+
+ const qreal underlineOffset = fe->underlinePosition().toReal();
// deliberately ceil the offset to avoid the underline coming too close to
// the text above it.
- const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal());
+ const qreal underlinePos = pos.y() + qCeil(underlineOffset);
if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
@@ -5957,16 +6071,18 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
if (underlineStyle == QTextCharFormat::WaveUnderline) {
painter->save();
- painter->setRenderHint(QPainter::Antialiasing);
- painter->translate(pos.x(), underlinePos);
+ painter->translate(0, pos.y() + 1);
QColor uc = ti.charFormat.underlineColor();
if (uc.isValid())
- painter->setPen(uc);
+ pen.setColor(uc);
- painter->drawPath(generateWavyPath(ti.width.toReal(),
- fe->underlinePosition().toReal(),
- painter->device()));
+ // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
+ const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
+ const int descent = (int) ti.descent.toReal();
+
+ painter->setBrushOrigin(painter->brushOrigin().x(), 0);
+ painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave);
painter->restore();
} else if (underlineStyle != QTextCharFormat::NoUnderline) {
QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
@@ -6001,10 +6117,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setBrush(oldBrush);
}
-/*!
- \internal
- \since 4.1
-*/
void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
{
#ifdef QT_DEBUG_DRAW
@@ -7602,7 +7714,7 @@ start_lengthVariant:
// in the paint engines when drawing on floating point offsets
const qreal scale = painter->transform().m22();
if (scale != 0)
- yoff = qRound(yoff * scale) / scale;
+ yoff = -qRound(-yoff * scale) / scale;
}
}
}
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 51d6195..a41ab6d 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -1209,7 +1209,7 @@ static qreal computeAngle(const QPointF &v)
}
#else
// doesn't seem to be robust enough
- return atan2(v.x(), v.y()) + Q_PI;
+ return qAtan2(v.x(), v.y()) + Q_PI;
#endif
}
diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp
index 6684ff7..930785b 100644
--- a/src/gui/painting/qprinterinfo_unix.cpp
+++ b/src/gui/painting/qprinterinfo_unix.cpp
@@ -75,7 +75,9 @@ private:
QString m_name;
bool m_isNull;
bool m_default;
- QList<QPrinter::PaperSize> m_paperSizes;
+ mutable bool m_mustGetPaperSizes;
+ mutable QList<QPrinter::PaperSize> m_paperSizes;
+ int m_cupsPrinterIndex;
QPrinterInfo* q_ptr;
};
@@ -838,16 +840,7 @@ QList<QPrinterInfo> QPrinterInfo::availablePrinters()
list.append(QPrinterInfo(printerName));
if (cupsPrinters[i].is_default)
list[i].d_ptr->m_default = true;
- // Find paper sizes.
- cups.setCurrentPrinter(i);
- const ppd_option_t* sizes = cups.pageSizes();
- if (sizes) {
- for (int j = 0; j < sizes->num_choices; ++j) {
- list[i].d_ptr->m_paperSizes.append(
- QPrinterInfoPrivate::string2PaperSize(
- QLatin1String(sizes->choices[j].choice)));
- }
- }
+ list[i].d_ptr->m_cupsPrinterIndex = i;
}
} else {
#endif
@@ -909,16 +902,7 @@ QPrinterInfo::QPrinterInfo(const QPrinter& printer)
if (printerName == printer.printerName()) {
if (cupsPrinters[i].is_default)
d->m_default = true;
- // Find paper sizes.
- cups.setCurrentPrinter(i);
- const ppd_option_t* sizes = cups.pageSizes();
- if (sizes) {
- for (int j = 0; j < sizes->num_choices; ++j) {
- d->m_paperSizes.append(
- QPrinterInfoPrivate::string2PaperSize(
- QLatin1String(sizes->choices[j].choice)));
- }
- }
+ d->m_cupsPrinterIndex = i;
return;
}
}
@@ -983,6 +967,26 @@ bool QPrinterInfo::isDefault() const
QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
{
const Q_D(QPrinterInfo);
+ if (d->m_mustGetPaperSizes) {
+ d->m_mustGetPaperSizes = false;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ QCUPSSupport cups;
+ if (QCUPSSupport::isAvailable()) {
+ // Find paper sizes from CUPS.
+ cups.setCurrentPrinter(d->m_cupsPrinterIndex);
+ const ppd_option_t* sizes = cups.pageSizes();
+ if (sizes) {
+ for (int j = 0; j < sizes->num_choices; ++j) {
+ d->m_paperSizes.append(
+ QPrinterInfoPrivate::string2PaperSize(
+ QLatin1String(sizes->choices[j].choice)));
+ }
+ }
+ }
+#endif
+
+ }
return d->m_paperSizes;
}
@@ -993,6 +997,8 @@ QPrinterInfoPrivate::QPrinterInfoPrivate()
{
m_isNull = true;
m_default = false;
+ m_mustGetPaperSizes = true;
+ m_cupsPrinterIndex = 0;
q_ptr = 0;
}
@@ -1001,6 +1007,8 @@ QPrinterInfoPrivate::QPrinterInfoPrivate(const QString& name)
m_name = name;
m_isNull = false;
m_default = false;
+ m_mustGetPaperSizes = true;
+ m_cupsPrinterIndex = 0;
q_ptr = 0;
}
diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h
index 2a1be86..f99fbf6 100644
--- a/src/gui/painting/qregion.h
+++ b/src/gui/painting/qregion.h
@@ -116,7 +116,9 @@ public:
QRect boundingRect() const;
QVector<QRect> rects() const;
void setRects(const QRect *rect, int num);
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numRects() const;
+#endif
int rectCount() const;
const QRegion operator|(const QRegion &r) const;
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 228a6b1..8bb4728 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -910,8 +910,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt
}
}
- int startSegment = int(floor(startAngle / 90));
- int endSegment = int(floor((startAngle + sweepLength) / 90));
+ int startSegment = int(qFloor(startAngle / 90));
+ int endSegment = int(qFloor((startAngle + sweepLength) / 90));
qreal startT = (startAngle - startSegment * 90) / 90;
qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 57473d1..bb0c630 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -76,7 +76,7 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache
{
public:
QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
- : QFontEngineGlyphCache(matrix), m_w(0), m_h(0), m_cx(0), m_cy(0), m_type(type) { }
+ : QFontEngineGlyphCache(matrix, type), m_w(0), m_h(0), m_cx(0), m_cy(0) { }
virtual ~QTextureGlyphCache() { }
@@ -98,8 +98,6 @@ public:
virtual void resizeTextureData(int width, int height) = 0;
virtual int glyphMargin() const { return 0; }
- QFontEngineGlyphCache::Type cacheType() const { return m_type; }
-
virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0;
inline void createCache(int width, int height) {
@@ -121,7 +119,6 @@ protected:
int m_h; // image height
int m_cx; // current x
int m_cy; // current y
- QFontEngineGlyphCache::Type m_type;
};
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index c66da71..15427c6 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -68,12 +68,14 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
mode = EColor16MA; // Try for transparency anyway
// 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
+ CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
- data->fromSymbianBitmap(bitmap);
- d_ptr->device = QPixmap(data);
+ if (data) {
+ data->fromSymbianBitmap(bitmap, true);
+ d_ptr->device = QPixmap(data);
+ }
setStaticContentsSupport(true);
}
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index 5028e5f..c1beb6a 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -2775,7 +2775,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
int w = size.width();
int h = size.height();
- int midHeight = static_cast<int>(ceil(float(tr.height() - h) / 2));
+ int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
int midWidth = ((tr.width() - w) / 2);
bool atTheTop = true;
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index b32c55b..e10bb41 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -645,6 +645,15 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg
return buttonsHaveIcons;
}
+ case SH_UnderlineShortcut: {
+ gboolean underlineShortcut = true;
+ if (!d->gtk_check_version(2, 12, 0)) {
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL);
+ }
+ return underlineShortcut;
+ }
+
default:
return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
}
@@ -3366,12 +3375,28 @@ QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
/*! \reimp */
QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
{
+ Q_D(const QGtkStyle);
+
QRect r = QCleanlooksStyle::subElementRect(element, option, widget);
switch (element) {
case SE_ProgressBarLabel:
case SE_ProgressBarContents:
case SE_ProgressBarGroove:
return option->rect;
+ case SE_PushButtonContents:
+ if (!d->gtk_check_version(2, 10, 0)) {
+ GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton"));
+ GtkBorder *border = 0;
+ d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL);
+ if (border) {
+ r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom);
+ d->gtk_border_free(border);
+ } else {
+ r = option->rect.adjusted(1, 1, -1, -1);
+ }
+ r = visualRect(option->direction, option->rect, r);
+ }
+ break;
default:
break;
}
diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp
index 5f4ebae..a644a5b 100644
--- a/src/gui/styles/qgtkstyle_p.cpp
+++ b/src/gui/styles/qgtkstyle_p.cpp
@@ -158,6 +158,7 @@ Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0;
Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0;
Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0;
Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0;
+Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0;
Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0;
Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0;
@@ -202,8 +203,12 @@ Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0;
typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
+QT_END_NAMESPACE
+
Q_DECLARE_METATYPE(QGtkStylePrivate*);
+QT_BEGIN_NAMESPACE
+
static void gtkStyleSetCallback(GtkWidget*)
{
qRegisterMetaType<QGtkStylePrivate *>();
@@ -412,6 +417,7 @@ void QGtkStylePrivate::resolveGtk() const
gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
+ gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free");
pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h
index f6ab8a3..c27308f 100644
--- a/src/gui/styles/qgtkstyle_p.h
+++ b/src/gui/styles/qgtkstyle_p.h
@@ -176,6 +176,7 @@ typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title,
typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *);
typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name);
typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*);
+typedef void (*Ptr_gtk_border_free)(GtkBorder *);
typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf);
typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf);
@@ -371,6 +372,7 @@ public:
static Ptr_gtk_widget_get_type gtk_widget_get_type;
static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths;
static Ptr_gtk_check_version gtk_check_version;
+ static Ptr_gtk_border_free gtk_border_free;
static Ptr_pango_font_description_get_size pango_font_description_get_size;
static Ptr_pango_font_description_get_weight pango_font_description_get_weight;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index dca78ca..bcc993a 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -84,23 +84,15 @@ extern Q_GUI_EXPORT int qt_defaultDpiY();
const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFlags =
SkinElementFlags(SF_PointNorth | SF_StateEnabled);
-static const QByteArray propertyKeyLayouts = "layouts";
-static const QByteArray propertyKeyCurrentlayout = "currentlayout";
-
static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,15,true,"QVGA Landscape Mirrored"},
-{240,320,1,15,false,"QVGA Landscape"},
-{320,240,1,15,true,"QVGA Portrait Mirrored"},
-{320,240,1,15,false,"QVGA Portrait"},
-{360,640,1,15,true,"NHD Landscape Mirrored"},
-{360,640,1,15,false,"NHD Landscape"},
-{640,360,1,15,true,"NHD Portrait Mirrored"},
-{640,360,1,15,false,"NHD Portrait"},
-{352,800,1,12,true,"E90 Landscape Mirrored"},
-{352,800,1,12,false,"E90 Landscape"}
+{240,320,1,15,"QVGA Landscape"},
+{320,240,1,15,"QVGA Portrait"},
+{360,640,1,15,"NHD Landscape"},
+{640,360,1,15,"NHD Portrait"},
+{352,800,1,12,"E90 Landscape"}
// *** End of generated data ***
};
const int QS60StylePrivate::m_numberOfLayouts =
@@ -108,15 +100,10 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,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,3,3,4,9,13,-909,5,51,11,5,0,6,3,3,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,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,3,3,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},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,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,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,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,4,4,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},
-{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,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,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,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,5,5,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},
-{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,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,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,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,5,5,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},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,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,5,-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,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1},
{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,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}
// *** End of generated data ***
};
@@ -203,10 +190,24 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
break;
case SE_SliderHandleHorizontal:
- drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth);
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointNorth);
break;
case SE_SliderHandleVertical:
- drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast);
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderHandleSelectedHorizontal:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SliderHandleSelectedVertical:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveVertical:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveHorizontal:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
break;
case SE_TabBarTabEastActive:
drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
@@ -309,8 +310,8 @@ QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *opt
QColor hsvColor = retColor.toHsv();
int colorSat = hsvColor.saturation();
int colorVal = hsvColor.value();
- colorSat = (colorSat!=0) ? (colorSat>>1) : 128;
- colorVal = (colorVal!=0) ? (colorVal>>1) : 128;
+ colorSat = (colorSat != 0) ? (colorSat >> 1) : 128;
+ colorVal = (colorVal != 0) ? (colorVal >> 1) : 128;
hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal);
retColor = hsvColor.toRgb();
}
@@ -338,7 +339,7 @@ QColor QS60StylePrivate::lighterColor(const QColor &baseColor)
bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget)
{
- return qobject_cast<const QDialog *> (widget);
+ return (widget ? (widget->windowType() == Qt::Dialog) : false);
}
QFont QS60StylePrivate::s60Font(
@@ -371,7 +372,6 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason)
case CC_LayoutChange:
// when layout changes, the colors remain in cache, but graphics and fonts can change
m_mappedFontsCache.clear();
- deleteBackground();
QPixmapCache::clear();
break;
case CC_ThemeChange:
@@ -399,10 +399,10 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
if (!cachedColorExists) {
const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth);
const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight);
- Q_ASSERT(2*frameCornerWidth<32);
- Q_ASSERT(2*frameCornerHeight<32);
+ Q_ASSERT(2 * frameCornerWidth < 32);
+ Q_ASSERT(2 * frameCornerHeight < 32);
- const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage();
+ const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage();
Q_ASSERT(frameImage.bytesPerLine() > 0);
if (frameImage.isNull())
return Qt::black;
@@ -417,14 +417,14 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
int skips = 0;
int estimations = 0;
- const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1;
- const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1;
- const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth;
+ const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1;
+ const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1;
+ const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth;
const int leftBorderLastPixel = frameCornerWidth;
while ((skips + estimations) < pixels) {
- if ((skips+estimations) > topBorderLastPixel &&
- (skips+estimations) < bottomBorderFirstPixel) {
+ if ((skips + estimations) > topBorderLastPixel &&
+ (skips + estimations) < bottomBorderFirstPixel) {
for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) {
if (rowIndex > leftBorderLastPixel &&
rowIndex < rightBorderFirstPixel) {
@@ -454,9 +454,6 @@ void QS60StylePrivate::setThemePalette(QApplication *app) const
Q_UNUSED(app)
QPalette widgetPalette = QPalette(Qt::white);
setThemePalette(&widgetPalette);
- QApplication::setPalette(widgetPalette); //calling QApplication::setPalette clears palette hash
- setThemePaletteHash(&widgetPalette);
- storeThemePalette(&widgetPalette);
}
QPalette* QS60StylePrivate::themePalette()
@@ -470,8 +467,6 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
QPalette applicationPalette = QApplication::palette();
applicationPalette.setBrush(QPalette::Window, backgroundTexture());
setThemePalette(&applicationPalette);
- QApplication::setPalette(applicationPalette);
- setThemePaletteHash(&applicationPalette);
}
void QS60StylePrivate::deleteBackground()
@@ -534,18 +529,18 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start,
endRect = startRect.translated(rect.width() - startRect.width(), 0);
middleRect.adjust(startRect.width(), 0, -startRect.width(), 0);
if (startRect.bottomRight().x() > endRect.topLeft().x()) {
- const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1;
- startRect.setWidth(startRect.width()-overlap);
- endRect.adjust(overlap,0,0,0);
+ const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1;
+ startRect.setWidth(startRect.width() - overlap);
+ endRect.adjust(overlap, 0, 0, 0);
}
} else {
startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height()));
endRect = startRect.translated(0, rect.height() - startRect.height());
middleRect.adjust(0, startRect.height(), 0, -startRect.height());
if (startRect.topRight().y() > endRect.bottomLeft().y()) {
- const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1;
- startRect.setHeight(startRect.height()-overlap);
- endRect.adjust(0,overlap,0,0);
+ const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1;
+ startRect.setHeight(startRect.height() - overlap);
+ endRect.adjust(0, overlap, 0, 0);
}
}
@@ -659,7 +654,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::WindowText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
palette->setColor(QPalette::ButtonText,
- s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 20, 0));
palette->setColor(QPalette::Text,
s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
palette->setColor(QPalette::ToolTipText,
@@ -687,6 +682,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125));
palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150));
palette->setColor(QPalette::Shadow, Qt::black);
+
+ QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash
+ setThemePaletteHash(palette);
+ storeThemePalette(palette);
}
void QS60StylePrivate::deleteThemePalette()
@@ -754,13 +753,15 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
QApplication::setPalette(widgetPalette, "QTableView");
widgetPalette = *palette;
+ widgetPalette.setColor(QPalette::Text,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0));
widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QLineEdit");
widgetPalette = *palette;
widgetPalette.setColor(QPalette::Text,
- s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0));
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0));
widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QTextEdit");
@@ -807,9 +808,17 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag
case QS60StyleEnums::SP_QgnGrafTabActiveL:
//Returned QSize for tabs must not be square, but narrow rectangle with width:height
//ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones).
- result.setWidth(result.height()>>1);
+ result.setWidth(result.height() >> 1);
break;
- case QS60StyleEnums::SP_QgnIndiSliderEdit:
+
+ case QS60StyleEnums::SP_QgnGrafNsliderEndLeft:
+ case QS60StyleEnums::SP_QgnGrafNsliderEndRight:
+ case QS60StyleEnums::SP_QgnGrafNsliderMiddle:
+ result.setWidth(result.height() >> 1);
+ break;
+
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
result.scale(pixelMetric(QStyle::PM_SliderLength),
pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
break;
@@ -930,22 +939,42 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
case CC_Slider:
if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- // The groove is just a centered line. Maybe a qgn_graf_line_* at some point
const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
- const QPoint sliderGrooveCenter = sliderGroove.center();
const bool horizontal = optionSlider->orientation == Qt::Horizontal;
- painter->save();
- if (widget)
- painter->setPen(widget->palette().windowText().color());
- if (horizontal)
- painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
- else
- painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
- painter->restore();
+ //Highlight
+/* if (optionSlider->state & QStyle::State_HasFocus)
+ drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
+
+ //Groove graphics
+ if (QS60StylePrivate::hasSliderGrooveGraphic()) {
+ const QS60StylePrivate::SkinElements grooveElement = horizontal ?
+ QS60StylePrivate::SE_SliderGrooveHorizontal :
+ QS60StylePrivate::SE_SliderGrooveVertical;
+ QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
+ } else {
+ const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
+ const QPoint sliderGrooveCenter = sliderGroove.center();
+ const bool horizontal = optionSlider->orientation == Qt::Horizontal;
+ painter->save();
+ if (widget)
+ painter->setPen(widget->palette().windowText().color());
+ if (horizontal)
+ painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
+ else
+ painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
+ painter->restore();
+ }
+
+ //Handle graphics
const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
- const QS60StylePrivate::SkinElements handleElement =
- horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
+ QS60StylePrivate::SkinElements handleElement;
+ if (optionSlider->state & QStyle::State_Sunken)
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical;
+ else
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags);
}
break;
@@ -962,10 +991,11 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
buttonOption.QStyleOption::operator=(*cmb);
const int maxHeight = cmbxFrame.height();
const int maxWidth = cmbxFrame.width() - cmbxEditField.width();
- const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth;
+ const int topLeftPoint = direction ?
+ (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth);
const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight);
buttonOption.rect = buttonRect;
- buttonOption.state = cmb->state & (State_Enabled | State_MouseOver);
+ buttonOption.state = cmb->state;
drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget);
// draw label background - label itself is drawn separately
@@ -1319,6 +1349,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->setClipRect(voptAdj.rect);
const bool isSelected = (vopt->state & QStyle::State_Selected);
+ const bool hasFocus = (vopt->state & QStyle::State_HasFocus);
bool isScrollBarVisible = false;
int scrollBarWidth = 0;
@@ -1350,9 +1381,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
const QModelIndex index = vopt->index;
//todo: Draw cell background only once - for the first cell.
QStyleOptionViewItemV4 voptAdj2 = voptAdj;
- const QModelIndex indexFirst = itemView->model()->index(0,0);
+ const QModelIndex indexFirst = itemView->model()->index(0, 0);
const QModelIndex indexLast = itemView->model()->index(
- itemView->model()->rowCount()-1,itemView->model()->columnCount()-1);
+ itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1);
if (itemView->viewport())
voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(),
itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect());
@@ -1361,7 +1392,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
} else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);}
// draw the focus rect
- if (isSelected) {
+ if (isSelected | hasFocus) {
QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
QAbstractItemView::SelectionBehavior selectionBehavior =
itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
@@ -1540,16 +1571,16 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
f.setPointSizeF(f.pointSizeF() * KTabFontMul);
painter->setFont(f);
- if (option->state & QStyle::State_Selected){
+ const bool selected = optionTab.state & State_Selected;
+ if (selected)
optionTab.palette.setColor(QPalette::Active, QPalette::WindowText,
QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option));
- }
const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast
|| optionTab.shape == QTabBar::RoundedWest
|| optionTab.shape == QTabBar::TriangularEast
|| optionTab.shape == QTabBar::TriangularWest;
- const bool selected = optionTab.state & State_Selected;
+
if (verticalTabs) {
painter->save();
int newX, newY, newRotation;
@@ -1587,12 +1618,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
(optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
if (tab->text.isEmpty())
- painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1),
- tr.center().y() - (tabIcon.height() >>1),
+ painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1),
+ tr.center().y() - (tabIcon.height() >> 1),
tabIcon);
else
painter->drawPixmap(tr.left() + tabOverlap,
- tr.center().y() - (tabIcon.height() >>1),
+ tr.center().y() - (tabIcon.height() >> 1),
tabIcon);
tr.setLeft(tr.left() + iconSize.width() + 4);
}
@@ -1621,7 +1652,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (optionProgressBar->orientation == Qt::Horizontal) {
progressRect.setWidth(int(progressRect.width() * progressFactor));
if(optionProgressBar->direction == Qt::RightToLeft)
- progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0);
+ progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0);
progressRect.adjust(1, 0, -1, 0);
} else {
progressRect.adjust(0, 1, 0, -1);
@@ -1687,18 +1718,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
- const int moveByX = optionCheckBox.rect.width()+vSpacing;
+ const int moveByX = optionCheckBox.rect.width() + vSpacing;
if (optionMenuItem.direction == Qt::LeftToRight) {
- textRect.translate(moveByX,0);
+ textRect.translate(moveByX, 0);
iconRect.translate(moveByX, 0);
- iconRect.setWidth(iconRect.width()+vSpacing);
- textRect.setWidth(textRect.width()-moveByX-vSpacing);
- optionCheckBox.rect.translate(vSpacing/2, hSpacing/2);
+ iconRect.setWidth(iconRect.width() + vSpacing);
+ textRect.setWidth(textRect.width() - moveByX - vSpacing);
+ optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1);
} else {
- textRect.setWidth(textRect.width()-moveByX);
- iconRect.setWidth(iconRect.width()+vSpacing);
- iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0);
- optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0);
+ textRect.setWidth(textRect.width() - moveByX);
+ iconRect.setWidth(iconRect.width() + vSpacing);
+ iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0);
+ optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0);
}
drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget);
}
@@ -1709,9 +1740,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (itemWithIcon) {
drawItemPixmap(painter, iconRect, text_flags, pix);
if (optionMenuItem.direction == Qt::LeftToRight)
- textRect.translate(vSpacing,0);
+ textRect.translate(vSpacing, 0);
else
- textRect.translate(-vSpacing,0);
+ textRect.translate(-vSpacing, 0);
textRect.setWidth(textRect.width()-vSpacing);
}
@@ -1719,7 +1750,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (drawSubMenuIndicator) {
QStyleOptionMenuItem arrowOptions;
arrowOptions.QStyleOption::operator=(*menuItem);
- const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) +
+ const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) +
pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget);
if (optionMenuItem.direction == Qt::LeftToRight)
arrowOptions.rect.setLeft(textRect.right());
@@ -1764,8 +1795,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->save();
QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
const int penWidth = (header->orientation == Qt::Horizontal) ?
- linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
- : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
+ linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
+ : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
linePen.setWidth(penWidth);
painter->setPen(linePen);
if (header->orientation == Qt::Horizontal){
@@ -1784,7 +1815,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
//Make cornerButton slightly smaller so that it is not on top of table border graphic.
QStyleOptionHeader subopt = *header;
const int borderTweak =
- QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1;
+ QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
if (subopt.direction == Qt::LeftToRight)
subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
else
@@ -1877,9 +1908,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
} else {
const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
if (option->direction == Qt::LeftToRight)
- headerRect.adjust(-2*frameWidth, 0, 0, 0);
+ headerRect.adjust(-2 * frameWidth, 0, 0, 0);
else
- headerRect.adjust(0, 0, 2*frameWidth, 0);
+ headerRect.adjust(0, 0, 2 * frameWidth, 0);
}
if (option->palette.brush(QPalette::Button).color() == Qt::transparent)
QS60StylePrivate::drawSkinElement(
@@ -2002,7 +2033,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
QRect tickRect = option->rect;
const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
// adjust tickmark rect to exclude frame border
- tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth);
+ tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth);
QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd;
QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect,
(flags | QS60StylePrivate::SF_ColorSkinned));
@@ -2014,7 +2045,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorRadioButton: {
QRect buttonRect = option->rect;
//there is empty (a. 33%) space in svg graphics for radiobutton
- const qreal reduceWidth = (qreal)buttonRect.width()/3.0;
+ const qreal reduceWidth = (qreal)buttonRect.width() / 3.0;
const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0;
// Try to occupy the full area
const qreal scaler = 1 + (reduceWidth/rectWidth);
@@ -2077,27 +2108,28 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorSpinDown:
case PE_IndicatorSpinUp:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- QStyleOptionSpinBox optionSpinBox = *spinBox;
- if (QS60StylePrivate::canDrawThemeBackground(optionSpinBox.palette.base())) {
+ if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) {
+ QStyleOptionSpinBox optionSpinBox = *spinBox;
const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
QS60StyleEnums::SP_QgnGrafScrollArrowUp :
QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6;
- optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags);
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+ optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags);
} else {
commonStyleDraws = true;
}
}
+#endif //QT_NO_SPINBOX
#ifndef QT_NO_COMBOBOX
- else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) {
// We want to draw down arrow here for comboboxes as well.
+ QStyleOptionFrame optionsComboBox = *cmb;
const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- QStyleOptionFrame comboBox = *cmb;
- const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6;
- comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags);
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+ optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags);
} else {
commonStyleDraws = true;
}
@@ -2115,12 +2147,11 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
// We want to draw down arrow here for comboboxes as well.
QStyleOptionFrame comboBox = *cmb;
const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- comboBox.rect.adjust(0,frameWidth,0,-frameWidth);
+ comboBox.rect.adjust(0, frameWidth, 0, -frameWidth);
QCommonStyle::drawPrimitive(element, &comboBox, painter, widget);
}
#endif //QT_NO_COMBOBOX
break;
-#endif //QT_NO_SPINBOX
case PE_Widget:
if (QS60StylePrivate::drawsOwnThemeBackground(widget)
#ifndef QT_NO_COMBOBOX
@@ -2130,7 +2161,10 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
|| qobject_cast<const QMenu *> (widget)
#endif //QT_NO_MENU
) {
- if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()))
+ //Need extra check since dialogs have their own theme background
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) &&
+ option->palette.window().texture().cacheKey() ==
+ QS60StylePrivate::m_themePalette->window().texture().cacheKey())
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags);
else
commonStyleDraws = true;
@@ -2240,11 +2274,13 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
}
break;
+ case PE_PanelScrollAreaCorner:
+ break;
+
// todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
case PE_FrameLineEdit:
case PE_IndicatorDockWidgetResizeHandle:
case PE_PanelTipLabel:
- case PE_PanelScrollAreaCorner:
#ifndef QT_NO_TABBAR
case PE_IndicatorTabTear: // No tab tear in S60
@@ -2286,6 +2322,13 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
metricValue = -menuWidth;
}
}
+ //if layout direction is mirrored, switch left and right border margins
+ if (option && option->direction == Qt::RightToLeft) {
+ if (metric == PM_LayoutLeftMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutRightMargin);
+ else if (metric == PM_LayoutRightMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin);
+ }
return metricValue;
}
@@ -2298,22 +2341,22 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_ToolButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
//FIXME properly - style should calculate the location of border frame-part
- sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
if (toolBtn->subControls & SC_ToolButtonMenu)
- sz += QSize(pixelMetric(PM_MenuButtonIndicator),0);
+ sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0);
break;
case CT_PushButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
//FIXME properly - style should calculate the location of border frame-part
- sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
if (buttonWidget->isCheckable())
sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
break;
case CT_LineEdit:
if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
- sz += QSize(2*f->lineWidth, 4*f->lineWidth);
+ sz += QSize(2 * f->lineWidth, 4 * f->lineWidth);
break;
case CT_TabBarTab:
{
@@ -2328,7 +2371,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (QS60StylePrivate::isTouchSupported())
//Make itemview easier to use in touch devices
//QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin));
+ sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin));
break;
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
@@ -2344,10 +2387,10 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
int retValue = -1;
switch (sh) {
case SH_Table_GridLineColor:
- retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgb();
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba());
break;
case SH_GroupBox_TextLabelColor:
- retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgb();
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba());
break;
case SH_ScrollBar_ScrollWhenPointerLeavesControl:
retValue = true;
@@ -2403,10 +2446,9 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
retValue = QFormLayout::WrapLongRows;
break;
default:
+ retValue = QCommonStyle::styleHint(sh, opt, widget, hret);
break;
}
- if (retValue == -1)
- retValue = QCommonStyle::styleHint(sh, opt, widget, hret);
return retValue;
}
@@ -2430,7 +2472,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep);
const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget);
- if (sliderlen < slidermin || range > (INT_MAX>>1))
+ if (sliderlen < slidermin || range > (INT_MAX >> 1))
sliderlen = slidermin;
if (sliderlen > maxlen)
sliderlen = maxlen;
@@ -2481,39 +2523,40 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
const int buttonMargin = spinbox->frame ? 2 : 0;
- const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin;
+ const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin;
QSize buttonSize;
buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness));
- buttonSize.setWidth(buttonWidth);
+ //width should at least be equal to height
+ buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth));
buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
const int y = frameThickness + spinbox->rect.y();
- const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width();
+ const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width();
switch (scontrol) {
case SC_SpinBoxUp:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
return QRect();
- ret = QRect(x, y, buttonWidth, buttonSize.height());
+ ret = QRect(x, y, buttonSize.width(), buttonSize.height());
break;
case SC_SpinBoxDown:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
return QRect();
- ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height());
+ ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height());
break;
case SC_SpinBoxEditField:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
ret = QRect(
frameThickness,
frameThickness,
- spinbox->rect.width() - 2*frameThickness,
- spinbox->rect.height() - 2*frameThickness);
+ spinbox->rect.width() - 2 * frameThickness,
+ spinbox->rect.height() - 2 * frameThickness);
else
ret = QRect(
frameThickness,
frameThickness,
x - frameThickness,
- spinbox->rect.height() - 2*frameThickness);
+ spinbox->rect.height() - 2 * frameThickness);
break;
case SC_SpinBoxFrame:
ret = spinbox->rect;
@@ -2529,29 +2572,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
ret = cmb->rect;
const int width = cmb->rect.width();
const int height = cmb->rect.height();
+ const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
const int buttonMargin = cmb->frame ? 2 : 0;
// lets use spinbox frame here as well, as no combobox specific value available.
const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0;
- const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
+ const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize);
+ const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth;
+ const int ypos = cmb->rect.y();
QSize buttonSize;
- buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels
- buttonSize.setWidth(buttonWidth+2*buttonMargin);
+ buttonSize.setWidth(buttonWidth + 2 * buttonMargin);
+ buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares
buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
switch (scontrol) {
case SC_ComboBoxArrow:
- ret.setRect(
- ret.x() + ret.width() - buttonMargin - buttonWidth,
- ret.y() + buttonMargin,
- buttonWidth,
- height - 2*buttonMargin);
+ ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin);
break;
case SC_ComboBoxEditField: {
- ret.setRect(
- ret.x() + frameThickness,
- ret.y() + frameThickness,
- ret.width() - 2*frameThickness - buttonSize.width(),
- ret.height() - 2*frameThickness);
+ const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width();
+ ret = QRect(
+ frameThickness,
+ frameThickness,
+ withFrameX - frameThickness,
+ cmb->rect.height() - 2 * frameThickness);
}
break;
default:
@@ -2568,7 +2611,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
//slightly indent text and boxes, so that dialog border does not mess with them.
const int horizontalSpacing =
QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
- ret.adjust(2,horizontalSpacing-3,0,0);
+ ret.adjust(2, horizontalSpacing - 3, 0, 0);
}
break;
case SC_GroupBoxFrame: {
@@ -2576,7 +2619,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
const int tbHeight = textBox.height();
ret.translate(0, -ret.y());
// include title to within the groupBox frame
- ret.setHeight(ret.height()+tbHeight);
+ ret.setHeight(ret.height() + tbHeight);
if (widget && ret.bottom() > widget->rect().bottom())
ret.setBottom(widget->rect().bottom());
}
@@ -2588,7 +2631,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
break;
case CC_ToolButton:
if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin);
+ const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2 * pixelMetric(PM_ButtonMargin);
const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth);
ret = toolButton->rect;
const bool popup = (toolButton->features &
@@ -2626,13 +2669,13 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
// in S60 the input text box doesn't start from line Edit's TL, but
// a bit indented.
QRect lineEditRect = opt->rect;
- const int adjustment = opt->rect.height()>>2;
- lineEditRect.adjust(adjustment,0,0,0);
+ const int adjustment = opt->rect.height() >> 2;
+ lineEditRect.adjust(adjustment, 0, 0, 0);
ret = lineEditRect;
}
break;
case SE_TabBarTearIndicator:
- ret = QRect(0,0,0,0);
+ ret = QRect(0, 0, 0, 0);
break;
case SE_TabWidgetTabBar:
if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
@@ -2654,12 +2697,12 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
// make sure that gain does not set the rect outside of widget boundaries
if (twf->direction == Qt::RightToLeft) {
if ((ret.left() - gain) < widget->rect().left())
- gain = widget->rect().left()-ret.left();
- ret.adjust(-gain,0,0,0);
+ gain = widget->rect().left() - ret.left();
+ ret.adjust(-gain, 0, 0, 0);
} else {
if ((ret.right() + gain) > widget->rect().right())
- gain = widget->rect().right()-ret.right();
- ret.adjust(0,0,gain,0);
+ gain = widget->rect().right() - ret.right();
+ ret.adjust(0, 0, gain, 0);
}
}
break;
@@ -2667,8 +2710,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
default: {
if (widget) {
if ((ret.bottom() + gain) > widget->rect().bottom())
- gain = widget->rect().bottom()-ret.bottom();
- ret.adjust(0,0,0,gain);
+ gain = widget->rect().bottom() - ret.bottom();
+ ret.adjust(0, 0, 0, gain);
}
break;
}
@@ -2694,7 +2737,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
//const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
- ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0);
+ ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0);
}
} else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
@@ -2719,9 +2762,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){
// submenu indicator is very small, so lets halve the rect
if (menuItem->direction == Qt::LeftToRight)
- ret.adjust(0,0,-(indicatorWidth >> 1),0);
+ ret.adjust(0, 0, -(indicatorWidth >> 1), 0);
else
- ret.adjust((indicatorWidth >> 1),0,0,0);
+ ret.adjust((indicatorWidth >> 1), 0, 0, 0);
}
}
}
@@ -2745,14 +2788,14 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
const int itemHeight = opt->rect.height();
int heightOffset = 0;
if (indicatorHeight < itemHeight)
- heightOffset = ((itemHeight - indicatorHeight)>>1);
+ heightOffset = ((itemHeight - indicatorHeight) >> 1);
if (checkBoxOnly) {
// Move rect and make it slightly smaller, so that
// a) highlight border does not cross the rect
// b) in s60 list checkbox is smaller than normal checkbox
//todo; magic three
- ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset,
- indicatorWidth-3, indicatorHeight-3);
+ ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset,
+ indicatorWidth - 3, indicatorHeight - 3);
} else {
ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset,
indicatorWidth, indicatorHeight);
@@ -2916,7 +2959,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option, const QWidget *widget) const
{
const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize);
- const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect;
+ const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect;
QS60StyleEnums::SkinParts part;
QS60StylePrivate::SkinElementFlags adjustedFlags;
if (option)
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 5ab2308..65d7574 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -119,6 +119,9 @@ public:
SP_QgnGrafTabPassiveL,
SP_QgnGrafTabPassiveM,
SP_QgnGrafTabPassiveR,
+ SP_QgnGrafNsliderEndLeft,
+ SP_QgnGrafNsliderEndRight,
+ SP_QgnGrafNsliderMiddle,
SP_QgnIndiCheckboxOff,
SP_QgnIndiCheckboxOn,
SP_QgnIndiHlColSuper, // Available in S60 release 3.2 and later.
@@ -131,7 +134,8 @@ public:
SP_QgnIndiNaviArrowRight,
SP_QgnIndiRadiobuttOff,
SP_QgnIndiRadiobuttOn,
- SP_QgnIndiSliderEdit,
+ SP_QgnGrafNsliderMarker,
+ SP_QgnGrafNsliderMarkerSelected,
SP_QgnIndiSubMenu,
SP_QgnNoteErased,
SP_QgnNoteError,
@@ -313,6 +317,10 @@ public:
SE_ScrollBarHandleVertical,
SE_SliderHandleHorizontal,
SE_SliderHandleVertical,
+ SE_SliderHandleSelectedHorizontal,
+ SE_SliderHandleSelectedVertical,
+ SE_SliderGrooveVertical,
+ SE_SliderGrooveHorizontal,
SE_TabBarTabEastActive,
SE_TabBarTabEastInactive,
SE_TabBarTabNorthActive,
@@ -403,6 +411,7 @@ public:
static bool isTouchSupported();
static bool isToolBarBackground();
+ static bool hasSliderGrooveGraphic();
// calculates average color based on button skin graphics (minus borders).
QColor colorFromFrameGraphics(SkinFrameElements frame) const;
@@ -443,7 +452,7 @@ public:
static QSize naviPaneSize();
//Checks that the current brush is transparent or has BrushStyle NoBrush,
- //so that theme graphic background can be drawn.
+ //so that theme graphic background can be drawn.
static bool canDrawThemeBackground(const QBrush &backgroundBrush);
private:
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 48b8fad..fb9665a 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -62,6 +62,7 @@
#include <AknLayoutFont.h>
#include <aknutils.h>
#include <aknnavi.h>
+#include <gulicon.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
@@ -69,6 +70,7 @@ QT_BEGIN_NAMESPACE
enum TDrawType {
EDrawIcon,
+ EDrawGulIcon,
EDrawBackground,
ENoDraw
};
@@ -80,8 +82,11 @@ enum TSupportRelease {
ES60_5_0 = 0x0004,
ES60_5_1 = 0x0008,
ES60_5_2 = 0x0010,
+ ES60_3_X = ES60_3_1 | ES60_3_2,
+ // Releases before Symbian Foundation
+ ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
// Add all new releases here
- ES60_AllReleases = 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
};
typedef struct {
@@ -101,11 +106,12 @@ public:
static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart,
const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
- static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format);
+ static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize& targetSize);
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);
private:
static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
@@ -115,209 +121,214 @@ private:
const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
- static void checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap);
- static void checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap);
- static void unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap);
- static void fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex);
+ static void fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex);
static bool checkSupport(const int supportedRelease);
- static TAknsItemID checkAndUpdateReleaseSpecificGraphics(int part);
// Array to match the skin ID, fallback graphics and Qt widget graphics.
static const partMapEntry m_partMap[];
};
const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
- /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_AllReleases, -1,-1},
+ /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
+ /* 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 3.1 there is no slider groove.
+ /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
+ /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
+ /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
+ /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
+
// Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
// In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
- /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
- /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
- /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
- /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
- /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
- /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiSliderEdit */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_AllReleases, -1,-1},
+ /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
+ /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
+ /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
+ /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
+ /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
+ /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
+
+ // In 3.1 there different slider graphic and no pressed state.
+ /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
+ /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
+ /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
// 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
- /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
- /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
- /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
-
- /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_AllReleases, -1,-1},
-
- /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_AllReleases, -1,-1},
-
- /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_AllReleases, -1,-1},
- /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, //todo: use "normal button" from 5.0 onwards
- /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleGSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleGSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleGSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleGSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_AllReleases, -1,-1},
-
- /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_AllReleases, -1,-1},
+ /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
+ /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
+ /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
+
+ /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_All, -1, -1},
+
+ /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleGSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleGSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleGSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleGSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_All, -1,-1},
// ToolTip graphics different in 3.1 vs. 3.2+.
- /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
- /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6},
- /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3},
- /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4},
- /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca},
- /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7},
- /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8},
- /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9},
- /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2},
-
- /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_AllReleases, -1,-1},
+ /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
+ /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6},
+ /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3},
+ /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4},
+ /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca},
+ /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7},
+ /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8},
+ /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9},
+ /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2},
+
+ /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_All, -1,-1},
// No toolbar frame for 5.0+ releases.
- /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
- /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1},
+ /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_X, -1,-1},
// Toolbar graphics is different in 3.1/3.2 vs. 5.0
- /* SP_QsnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
- /* SP_QsnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2302},
- /* SP_QsnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2303},
- /* SP_QsnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2304},
- /* SP_QsnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2305},
- /* SP_QsnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2306},
- /* SP_QsnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2307},
- /* SP_QsnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2308},
- /* SP_QsnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
+ /* SP_QsnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
+ /* SP_QsnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302},
+ /* SP_QsnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303},
+ /* SP_QsnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304},
+ /* SP_QsnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305},
+ /* SP_QsnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306},
+ /* SP_QsnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307},
+ /* SP_QsnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308},
+ /* SP_QsnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
// No pressed state for toolbar button in 3.1/3.2.
- /* SP_QsnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2621}, /*KAknsIIDQsnFrSctrlButtonCornerTlPressed*/
- /* SP_QsnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2622},
- /* SP_QsnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2623},
- /* SP_QsnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2624},
- /* SP_QsnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2625},
- /* SP_QsnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2626},
- /* SP_QsnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2627},
- /* SP_QsnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2628},
- /* SP_QsnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2629},
+ /* SP_QsnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQsnFrSctrlButtonCornerTlPressed*/
+ /* SP_QsnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622},
+ /* SP_QsnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623},
+ /* SP_QsnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624},
+ /* SP_QsnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625},
+ /* SP_QsnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626},
+ /* SP_QsnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627},
+ /* SP_QsnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628},
+ /* SP_QsnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629},
// No inactive button graphics in 3.1/3.2
- /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
- /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b2},
- /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b3},
- /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b4},
- /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b5},
- /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b6},
- /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b7},
- /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b8},
- /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b9},
+ /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b2},
+ /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b3},
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b4},
+ /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b5},
+ /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b6},
+ /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b7},
+ /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b8},
+ /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_X, EAknsMajorSkin, 0x21b9},
};
@@ -349,7 +360,7 @@ QPixmap QS60StyleModeSpecifics::skinnedGraphics(
}
QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
- const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
+ const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
QS60StylePrivate::SkinElementFlags flags)
{
QPixmap colorGraphics;
@@ -357,155 +368,121 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
return error ? QPixmap() : colorGraphics;
}
-void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex)
+void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
{
- switch(stylepart) {
+ switch(stylePart) {
case QS60StyleEnums::SP_QgnGrafBarWait:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
break;
case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center;
break;
case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l;
break;
case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r;
break;
case QS60StyleEnums::SP_QgnGrafBarProgress:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_bar_progress;
break;
case QS60StyleEnums::SP_QgnGrafTabActiveL:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_active_l;
break;
case QS60StyleEnums::SP_QgnGrafTabActiveM:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_active_m;
break;
case QS60StyleEnums::SP_QgnGrafTabActiveR:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_active_r;
break;
case QS60StyleEnums::SP_QgnGrafTabPassiveL:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l;
break;
case QS60StyleEnums::SP_QgnGrafTabPassiveM:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m;
break;
case QS60StyleEnums::SP_QgnGrafTabPassiveR:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r;
break;
case QS60StyleEnums::SP_QgnIndiCheckboxOff:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_checkbox_off;
break;
case QS60StyleEnums::SP_QgnIndiCheckboxOn:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_checkbox_on;
break;
case QS60StyleEnums::SP_QgnIndiHlColSuper:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */
break;
case QS60StyleEnums::SP_QgnIndiHlExpSuper:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */
break;
case QS60StyleEnums::SP_QgnIndiHlLineBranch:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */
break;
case QS60StyleEnums::SP_QgnIndiHlLineEnd:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */
break;
case QS60StyleEnums::SP_QgnIndiHlLineStraight:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */
break;
case QS60StyleEnums::SP_QgnIndiMarkedAdd:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_marked_add;
break;
case QS60StyleEnums::SP_QgnIndiNaviArrowLeft:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left;
break;
case QS60StyleEnums::SP_QgnIndiNaviArrowRight:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right;
break;
case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off;
break;
case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
break;
- case QS60StyleEnums::SP_QgnIndiSliderEdit:
- fallbackFileName = KAvkonBitmapFile();
- fallbackIndex = EMbmAvkonQgn_indi_slider_edit;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
+ fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
break;
case QS60StyleEnums::SP_QgnIndiSubMenu:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_indi_submenu;
break;
case QS60StyleEnums::SP_QgnNoteErased:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_erased;
break;
case QS60StyleEnums::SP_QgnNoteError:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_error;
break;
case QS60StyleEnums::SP_QgnNoteInfo:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_info;
break;
case QS60StyleEnums::SP_QgnNoteOk:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_ok;
break;
case QS60StyleEnums::SP_QgnNoteQuery:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_query;
break;
case QS60StyleEnums::SP_QgnNoteWarning:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_note_warning;
break;
case QS60StyleEnums::SP_QgnPropFileSmall:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_prop_file_small;
break;
case QS60StyleEnums::SP_QgnPropFolderCurrent:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_prop_folder_current;
break;
case QS60StyleEnums::SP_QgnPropFolderSmall:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_prop_folder_small;
break;
case QS60StyleEnums::SP_QgnPropFolderSmallNew:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_prop_folder_small_new;
break;
case QS60StyleEnums::SP_QgnPropPhoneMemcLarge:
- fallbackFileName = KAvkonBitmapFile();
fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large;
break;
default:
- fallbackFileName = KNullDesC();
fallbackIndex = -1;
break;
}
@@ -521,8 +498,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
TInt fallbackGraphicID = -1;
HBufC* iconFile = HBufC::NewLC( KMaxFileName );
- TPtr fileNamePtr = iconFile->Des();
- fallbackInfo(stylepart, fileNamePtr, fallbackGraphicID);
+ fallbackInfo(stylepart, fallbackGraphicID);
TAknsItemID colorGroup = KAknsIIDQsnIconColors;
TRgb defaultColor = KRgbBlack;
@@ -543,10 +519,18 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
AknsUtils::CreateColorIconLC(
- skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, defaultColor);
- User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved));
- User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved));
- QPixmap result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode()));
+ skinInstance,
+ skinId,
+ colorGroup,
+ colorIndex,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID,
+ fallbackGraphicsMaskID,
+ defaultColor);
+
+ QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile
return result;
}
@@ -566,55 +550,43 @@ struct QAutoFbsBitmapHeapLock
CFbsBitmap* mBmp;
};
-QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format)
+QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize &targetSize)
{
Q_ASSERT(icon);
- const TSize iconSize = icon->SizeInPixels();
- const int iconBytesPerLine = CFbsBitmap::ScanLineLength(iconSize.iWidth, icon->DisplayMode());
- const int iconBytesCount = iconBytesPerLine * iconSize.iHeight;
- QImage iconImage(qt_TSize2QSize(iconSize), format);
- if (iconImage.isNull())
- return QPixmap();
+ AknIconUtils::DisableCompression(icon);
+ TInt error = AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved);
- checkAndUnCompressBitmap(icon);
- if (!icon) //checkAndUnCompressBitmap might set icon to NULL
+ if (mask && !error) {
+ AknIconUtils::DisableCompression(mask);
+ error = AknIconUtils::SetSize(mask, targetSize, EAspectRatioNotPreserved);
+ }
+ if (error)
return QPixmap();
- icon->LockHeap();
- const uchar *const iconBytes = (uchar*)icon->DataAddress();
- // The icon data needs to be copied, since the color format will be
- // automatically converted to Format_ARGB32 when setAlphaChannel is called.
- memcpy(iconImage.bits(), iconBytes, iconBytesCount);
- icon->UnlockHeap();
- if (mask) {
- checkAndUnCompressBitmap(mask);
- if (mask) { //checkAndUnCompressBitmap might set mask to NULL
- const TSize maskSize = icon->SizeInPixels();
- const int maskBytesPerLine = CFbsBitmap::ScanLineLength(maskSize.iWidth, mask->DisplayMode());
- // heap lock object required because QImage ctor might throw
- QAutoFbsBitmapHeapLock maskHeapLock(mask);
- const uchar *const maskBytes = (uchar *)mask->DataAddress();
- // Since no other bitmap should be locked, we can just "borrow" the mask data for setAlphaChannel
- const QImage maskImage(maskBytes, maskSize.iWidth, maskSize.iHeight, maskBytesPerLine, QImage::Format_Indexed8);
- if (!maskImage.isNull())
- iconImage.setAlphaChannel(maskImage);
+ QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(icon);
+ if (mask)
+ pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+
+ if ((flags & QS60StylePrivate::SF_PointEast) ||
+ (flags & QS60StylePrivate::SF_PointSouth) ||
+ (flags & QS60StylePrivate::SF_PointWest)) {
+ QImage iconImage = pixmap.toImage();
+ QTransform imageTransform;
+ if (flags & QS60StylePrivate::SF_PointEast) {
+ imageTransform.rotate(90);
+ } else if (flags & QS60StylePrivate::SF_PointSouth) {
+ imageTransform.rotate(180);
+ iconImage = iconImage.transformed(imageTransform);
+ } else if (flags & QS60StylePrivate::SF_PointWest) {
+ imageTransform.rotate(270);
}
- }
+ if (imageTransform.isRotating())
+ iconImage = iconImage.transformed(imageTransform);
- QTransform imageTransform;
- if (flags & QS60StylePrivate::SF_PointEast) {
- imageTransform.rotate(90);
- } else if (flags & QS60StylePrivate::SF_PointSouth) {
- imageTransform.rotate(180);
- iconImage = iconImage.transformed(imageTransform);
- } else if (flags & QS60StylePrivate::SF_PointWest) {
- imageTransform.rotate(270);
+ pixmap = QPixmap::fromImage(iconImage);
}
- if (imageTransform.isRotating())
- iconImage = iconImage.transformed(imageTransform);
-
- return QPixmap::fromImage(iconImage);
+ return pixmap;
}
bool QS60StylePrivate::isTouchSupported()
@@ -627,6 +599,11 @@ bool QS60StylePrivate::isToolBarBackground()
return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
}
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
+}
+
QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
{
CCoeControl *control = targetWidget->effectiveWinId();
@@ -645,7 +622,7 @@ QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
}
QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
- QS60StyleEnums::SkinParts part, const QSize &size,
+ QS60StyleEnums::SkinParts part, const QSize &size,
QS60StylePrivate::SkinElementFlags flags)
{
// this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
@@ -653,7 +630,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
return QPixmap();
// Check release support and change part, if necessary.
- const TAknsItemID skinId = checkAndUpdateReleaseSpecificGraphics((int)part);
+ const TAknsItemID skinId = partSpecificThemeId((int)part);
const int stylepartIndex = (int)part;
const TDrawType drawType = m_partMap[stylepartIndex].drawType;
Q_ASSERT(drawType != ENoDraw);
@@ -667,24 +644,34 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
QPixmap result;
switch (drawType) {
+ case EDrawGulIcon: {
+ CGulIcon* icon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), skinId, EFalse );
+ if (icon)
+ result = fromFbsBitmap(icon->Bitmap(), icon->Mask(), flags, targetSize);
+ delete icon;
+ break;
+ }
case EDrawIcon: {
TInt fallbackGraphicID = -1;
- HBufC* iconFile = HBufC::NewLC( KMaxFileName );
- TPtr fileNamePtr = iconFile->Des();
- fallbackInfo(part, fileNamePtr, fallbackGraphicID);
- // todo: could we instead use AknIconUtils::AvkonIconFileName(); to avoid allocating each time?
+ fallbackInfo(part, fallbackGraphicID);
CFbsBitmap *icon = 0;
CFbsBitmap *iconMask = 0;
const TInt fallbackGraphicsMaskID =
fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
- // QS60WindowSurface::unlockBitmapHeap();
- AknsUtils::CreateIconLC(skinInstance, skinId, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID);
- User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved));
- User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved));
- result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode()));
- CleanupStack::PopAndDestroy(3); // iconMask, icon, iconFile
- // QS60WindowSurface::lockBitmapHeap();
+
+ AknsUtils::CreateIconL(
+ skinInstance,
+ skinId,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+
+ result = fromFbsBitmap(icon, iconMask, flags, targetSize);
+ delete icon;
+ delete iconMask;
break;
}
case EDrawBackground: {
@@ -715,13 +702,16 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
KAknsDrawParamDefault | KAknsDrawParamRGBOnly);
if (drawn)
- result = fromFbsBitmap(background, NULL, flags, QImage::Format_RGB32);
+ result = fromFbsBitmap(background, NULL, flags, targetSize);
+ // if drawing fails in skin server, just ignore the background (probably OOM occured)
CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
// QS60WindowSurface::lockBitmapHeap();
break;
}
}
+ if (!result)
+ result = QPixmap();
return result;
}
@@ -755,24 +745,46 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
User::LeaveIfError(bitmapDev->CreateContext(bitmapGc));
CleanupStack::PushL(bitmapGc);
+#ifndef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
frame->LockHeap();
memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes
frame->UnlockHeap();
+#endif
const TRect outerRect(TPoint(0, 0), targetSize);
const TRect innerRect = innerRectFromElement(frameElement, outerRect);
TAknsItemID frameSkinID, centerSkinID;
- frameSkinID = centerSkinID = checkAndUpdateReleaseSpecificGraphics(QS60StylePrivate::m_frameElementsData[frameElement].center);
+ frameSkinID = centerSkinID = partSpecificThemeId(QS60StylePrivate::m_frameElementsData[frameElement].center);
frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
- const TBool drawn = AknsDrawUtils::DrawFrame( skinInstance,
- *bitmapGc, outerRect, innerRect,
- frameSkinID, centerSkinID,
- drawParam );
+
+ TBool drawn = AknsDrawUtils::DrawFrame(
+ skinInstance,
+ *bitmapGc,
+ outerRect,
+ innerRect,
+ frameSkinID,
+ centerSkinID,
+ drawParam );
if (S60->supportsPremultipliedAlpha) {
- if (drawn)
- result = fromFbsBitmap(frame, NULL, flags, QImage::Format_ARGB32_Premultiplied);
+ if (drawn) {
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ } else {
+ // Drawing might fail due to OOM (we can do nothing about that),
+ // or due to skin item not being available.
+ // If the latter occurs, lets try switch to non-release specific items (if available)
+ // and re-try the drawing.
+ frameSkinID = centerSkinID = m_partMap[(int)QS60StylePrivate::m_frameElementsData[frameElement].center].skinID;
+ frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
+ drawn = AknsDrawUtils::DrawFrame( skinInstance,
+ *bitmapGc, outerRect, innerRect,
+ frameSkinID, centerSkinID,
+ drawParam );
+ // in case drawing fails, even after using default graphics, ignore the error
+ if (drawn)
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ }
} else {
TDisplayMode maskDepth = EGray2;
// Query the skin item for possible frame graphics mask details.
@@ -802,11 +814,12 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
maskBitGc->Clear();
maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush);
- AknsDrawUtils::DrawFrame(skinInstance,
+ drawn = AknsDrawUtils::DrawFrame(skinInstance,
*maskBitGc, outerRect, innerRect,
frameSkinID, centerSkinID,
KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage);
- result = fromFbsBitmap(frame, frameMask, flags, QImage::Format_ARGB32);
+ if (drawn)
+ result = fromFbsBitmap(frame, frameMask, flags, targetSize);
}
CleanupStack::PopAndDestroy(3, frameMask);
}
@@ -880,10 +893,12 @@ bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) ||
(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_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));
}
-TAknsItemID QS60StyleModeSpecifics::checkAndUpdateReleaseSpecificGraphics(int part)
+TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
{
TAknsItemID newSkinId;
if (!checkSupport(m_partMap[(int)part].supportInfo))
@@ -893,33 +908,6 @@ TAknsItemID QS60StyleModeSpecifics::checkAndUpdateReleaseSpecificGraphics(int pa
return newSkinId;
}
-void QS60StyleModeSpecifics::checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap)
-{
- TRAPD(error, checkAndUnCompressBitmapL(aOriginalBitmap));
- if (error)
- aOriginalBitmap = NULL;
-}
-
-void QS60StyleModeSpecifics::checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap)
-{
- const TSize iconSize = aOriginalBitmap->SizeInPixels();
- const int iconBytesPerLine = CFbsBitmap::ScanLineLength(iconSize.iWidth, aOriginalBitmap->DisplayMode());
- const int iconBytesCount = iconBytesPerLine * iconSize.iHeight;
- if (aOriginalBitmap->IsCompressedInRAM() || aOriginalBitmap->Header().iBitmapSize < iconBytesCount) {
- const TSize iconSize(aOriginalBitmap->SizeInPixels().iWidth,
- aOriginalBitmap->SizeInPixels().iHeight);
- CFbsBitmap* uncompressedBitmap = new (ELeave) CFbsBitmap();
- CleanupStack::PushL(uncompressedBitmap);
- User::LeaveIfError(uncompressedBitmap->Create(iconSize,
- aOriginalBitmap->DisplayMode()));
- unCompressBitmapL(iconSize, uncompressedBitmap, aOriginalBitmap);
- CleanupStack::Pop(uncompressedBitmap);
- User::LeaveIfError(aOriginalBitmap->Duplicate(
- uncompressedBitmap->Handle()));
- delete uncompressedBitmap;
- }
-}
-
QFont QS60StylePrivate::s60Font_specific(
QS60StyleEnums::FontCategories fontCategory, int pointSize)
{
@@ -972,37 +960,23 @@ void QS60StylePrivate::setActiveLayout()
{
const QSize activeScreenSize(screenSize());
int activeLayoutIndex = -1;
- const bool mirrored = !QApplication::isLeftToRight();
const short screenHeight = (short)activeScreenSize.height();
const short screenWidth = (short)activeScreenSize.width();
for (int i=0; i<m_numberOfLayouts; i++) {
if (screenHeight==m_layoutHeaders[i].height &&
- screenWidth==m_layoutHeaders[i].width &&
- mirrored==m_layoutHeaders[i].mirroring) {
+ screenWidth==m_layoutHeaders[i].width) {
activeLayoutIndex = i;
break;
}
}
- //not found, lets try without mirroring info
- if (activeLayoutIndex==-1){
- for (int i=0; i<m_numberOfLayouts; i++) {
- if (screenHeight==m_layoutHeaders[i].height &&
- screenWidth==m_layoutHeaders[i].width) {
- activeLayoutIndex = i;
- break;
- }
- }
- }
-
//not found, lets try with either of dimensions
if (activeLayoutIndex==-1){
const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
const bool landscape = screenHeight < screenWidth;
- activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 4;
- activeLayoutIndex += (!landscape) ? 2 : 0;
- activeLayoutIndex += (!mirrored) ? 1 : 0;
+ activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
+ activeLayoutIndex += (!landscape) ? 1 : 0;
}
m_pmPointer = data[activeLayoutIndex];
@@ -1159,160 +1133,29 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin
QPixmap QS60StylePrivate::backgroundTexture()
{
+ bool createNewBackground = false;
if (!m_background) {
+ createNewBackground = true;
+ } else {
+ //if background brush does not match screensize, re-create it
+ if (m_background->width() != S60->screenWidthInPixels ||
+ m_background->height() != S60->screenHeightInPixels) {
+ delete m_background;
+ createNewBackground = true;
+ }
+ }
+
+ if (createNewBackground) {
QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags());
+ QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags());
m_background = new QPixmap(background);
}
return *m_background;
}
-// If the public SDK returns compressed images, please let us also uncompress those!
-void QS60StyleModeSpecifics::unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap)
-{
- if (!aSrcBitmap)
- User::Leave(KErrArgument);
- if (!aTrgBitmap)
- User::Leave(KErrArgument);
-
- // Note! aSrcBitmap->IsCompressedInRAM() is always ETrue, since this method is called only if that applies!
- // Extra note! this function is also being used when bitmaps appear to be compressed (because DataSize is too small)
- // even when they pretend they are not. Assert removed.
-// ASSERT(aSrcBitmap->IsCompressedInRAM());
-
- TDisplayMode displayMode = aSrcBitmap->DisplayMode();
-
- if (displayMode != aTrgBitmap->DisplayMode())
- User::Leave(KErrArgument);
-
- const TSize trgSize = aTrgBitmap->SizeInPixels();
- const TSize srcSize = aSrcBitmap->SizeInPixels();
-
- // calculate the valid drawing area
- TRect drawRect = aTrgRect;
- drawRect.Intersection(TRect(TPoint(0, 0), trgSize));
-
- if (drawRect.IsEmpty())
- return;
-
- CFbsBitmap* realSource = new (ELeave) CFbsBitmap();
- CleanupStack::PushL(realSource);
- User::LeaveIfError(realSource->Create(srcSize, displayMode));
- CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(realSource);
- CleanupStack::PushL(dev);
- CFbsBitGc* gc = NULL;
- User::LeaveIfError(dev->CreateContext(gc));
- CleanupStack::PushL(gc);
- gc->BitBlt(TPoint(0, 0), aSrcBitmap);
- CleanupStack::PopAndDestroy(2); // dev, gc
-
- // Heap lock for FBServ large chunk is only needed with large bitmaps.
- if (realSource->IsLargeBitmap() || aTrgBitmap->IsLargeBitmap()) {
- aTrgBitmap->LockHeapLC(ETrue); // fbsheaplock
- } else {
- CleanupStack::PushL((TAny*) NULL);
- }
-
- TUint32* srcAddress = realSource->DataAddress();
- TUint32* trgAddress = aTrgBitmap->DataAddress();
-
- const TInt xSkip = (srcSize.iWidth << 8) / aTrgRect.Width();
- const TInt ySkip = (srcSize.iHeight << 8) / aTrgRect.Height();
-
- const TInt drawWidth = drawRect.Width();
- const TInt drawHeight = drawRect.Height();
-
- const TRect offsetRect(aTrgRect.iTl, drawRect.iTl);
- const TInt yPosOffset = ySkip * offsetRect.Height();
- const TInt xPosOffset = xSkip * offsetRect.Width();
-
- if ((displayMode == EGray256) || (displayMode == EColor256)) {
- const TInt srcScanLen8 = CFbsBitmap::ScanLineLength(srcSize.iWidth,
- displayMode);
- const TInt trgScanLen8 = CFbsBitmap::ScanLineLength(trgSize.iWidth,
- displayMode);
-
- TUint8* trgAddress8 = reinterpret_cast<TUint8*> (trgAddress);
-
- TInt yPos = yPosOffset;
- // skip left and top margins in the beginning
- trgAddress8 += trgScanLen8 * drawRect.iTl.iY + drawRect.iTl.iX;
-
- for (TInt y = 0; y < drawHeight; y++) {
- const TUint8* srcAddress8 = reinterpret_cast<const TUint8*> (srcAddress)
- + (srcScanLen8 * (yPos >> 8));
-
- TInt xPos = xPosOffset;
- for (TInt x = 0; x < drawWidth; x++) {
- *(trgAddress8++) = srcAddress8[xPos >> 8];
- xPos += xSkip;
- }
-
- yPos += ySkip;
-
- trgAddress8 += trgScanLen8 - drawWidth;
- }
- } else if (displayMode == EColor4K || displayMode == EColor64K) {
- const TInt srcScanLen16 = CFbsBitmap::ScanLineLength(srcSize.iWidth,
- displayMode) >>1;
- const TInt trgScanLen16 = CFbsBitmap::ScanLineLength(trgSize.iWidth,
- displayMode) >>1;
-
- TUint16* trgAddress16 = reinterpret_cast<TUint16*> (trgAddress);
-
- TInt yPos = yPosOffset;
- // skip left and top margins in the beginning
- trgAddress16 += trgScanLen16 * drawRect.iTl.iY + drawRect.iTl.iX;
-
- for (TInt y = 0; y < drawHeight; y++) {
- const TUint16* srcAddress16 = reinterpret_cast<const TUint16*> (srcAddress)
- + (srcScanLen16 * (yPos >> 8));
-
- TInt xPos = xPosOffset;
- for (TInt x = 0; x < drawWidth; x++) {
- *(trgAddress16++) = srcAddress16[xPos >> 8];
- xPos += xSkip;
- }
-
- yPos += ySkip;
-
- trgAddress16 += trgScanLen16 - drawWidth;
- }
- } else if (displayMode == EColor16MU || displayMode == EColor16MA) {
- const TInt srcScanLen32 = CFbsBitmap::ScanLineLength(srcSize.iWidth,
- displayMode) >>2;
- const TInt trgScanLen32 = CFbsBitmap::ScanLineLength(trgSize.iWidth,
- displayMode) >>2;
-
- TUint32* trgAddress32 = reinterpret_cast<TUint32*> (trgAddress);
-
- TInt yPos = yPosOffset;
- // skip left and top margins in the beginning
- trgAddress32 += trgScanLen32 * drawRect.iTl.iY + drawRect.iTl.iX;
-
- for (TInt y = 0; y < drawHeight; y++) {
- const TUint32* srcAddress32 = reinterpret_cast<const TUint32*> (srcAddress)
- + (srcScanLen32 * (yPos >> 8));
-
- TInt xPos = xPosOffset;
- for (TInt x = 0; x < drawWidth; x++) {
- *(trgAddress32++) = srcAddress32[xPos >> 8];
- xPos += xSkip;
- }
-
- yPos += ySkip;
-
- trgAddress32 += trgScanLen32 - drawWidth;
- }
- } else { User::Leave(KErrUnknown);}
-
- CleanupStack::PopAndDestroy(2); // fbsheaplock, realSource
-}
-
QSize QS60StylePrivate::screenSize()
{
- const TSize screenSize = QS60Data::screenDevice()->SizeInPixels();
- return QSize(screenSize.iWidth, screenSize.iHeight);
+ return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
}
QS60Style::QS60Style()
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 55d5771..e49854f 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -337,6 +337,11 @@ bool QS60StylePrivate::isToolBarBackground()
return true;
}
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return false;
+}
+
QFont QS60StylePrivate::s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize)
{
QFont result;
diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp
index af30f15..f5af960 100644
--- a/src/gui/styles/qstylehelper.cpp
+++ b/src/gui/styles/qstylehelper.cpp
@@ -154,7 +154,7 @@ qreal angle(const QPointF &p1, const QPointF &p2)
}
qreal m = -(y2 - y1) / (x2 - x1);
- _angle = atan(m) * rad_factor;
+ _angle = qAtan(m) * rad_factor;
if (p1.x() < p2.x())
_angle = 180 - _angle;
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 8b40931..aff3ac0 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1065,7 +1065,7 @@ QRect QRenderRule::boxRect(const QRect& cr, int flags) const
r.adjust(-p[LeftEdge], -p[TopEdge], p[RightEdge], p[BottomEdge]);
}
}
- if (!hasNativeBorder() && (flags & Border)) {
+ if (hasBorder() && (flags & Border)) {
const int *b = border()->borders;
r.adjust(-b[LeftEdge], -b[TopEdge], b[RightEdge], b[BottomEdge]);
}
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
index fe7f5d7..50be342 100644
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ b/src/gui/styles/qwindowsxpstyle.cpp
@@ -623,8 +623,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
painter->save();
- QMatrix m = painter->matrix();
- bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0;
+ bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
bool translucentToplevel = false;
QPaintDevice *pdev = painter->device();
@@ -3780,12 +3779,19 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData);
const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
if (mask && titlebar) {
+ // Note certain themes will not return the whole window frame but only the titlebar part when
+ // queried This function needs to return the entire window mask, hence we will only fetch the mask for the
+ // titlebar itself and add the remaining part of the window rect at the bottom.
+ int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
+ QRect titleBarRect = option->rect;
+ titleBarRect.setHeight(tbHeight);
XPThemeData themeData;
if (titlebar->titleBarState & Qt::WindowMinimized) {
- themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, option->rect);
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
} else
- themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, option->rect);
- mask->region = d->region(themeData);
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
+ mask->region = d->region(themeData) +
+ QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
}
}
break;
diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri
index 88a2cce..7e5c55a 100644
--- a/src/gui/styles/styles.pri
+++ b/src/gui/styles/styles.pri
@@ -168,7 +168,7 @@ contains( styles, s60 ):contains(QT_CONFIG, s60) {
SOURCES += styles/qs60style.cpp
symbian {
SOURCES += styles/qs60style_s60.cpp
- LIBS += -laknicon -laknskins -laknskinsrv -lfontutils
+ LIBS += -laknicon -laknskins -laknskinsrv -lfontutils -legul
} else {
SOURCES += styles/qs60style_simulated.cpp
RESOURCES += styles/qstyle_s60_simulated.qrc
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7e93aa0..e9c7b89 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -1482,13 +1482,13 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo)
and style will look attractive.
If the font family is available from two or more foundries the
- foundry name is included in the family name, e.g. "Helvetica
- [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
- can either use the old hyphenated Qt 2.x "foundry-family" format,
- e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family
- [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
- foundry it is always returned, e.g. by families(), using the
- bracketed format.
+ foundry name is included in the family name; for example:
+ "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
+ family, you can either use the old hyphenated "foundry-family"
+ format or the bracketed "family [foundry]" format; for example:
+ "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
+ foundry it is always returned using the bracketed format, as is
+ the case with the value returned by families().
The font() function returns a QFont given a family, style and
point size.
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index 808dca6..bf8af92 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -51,6 +51,9 @@
#include <private/qcore_symbian_p.h>
#if defined(QT_NO_FREETYPE)
#include <OPENFONT.H>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file
+#endif // SYMBIAN_ENABLE_SPLIT_HEADERS
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 27fc3c1..d364025 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -185,22 +185,11 @@ QFontEngine::QFontEngine()
QFontEngine::~QFontEngine()
{
- for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(),
- end = m_glyphPointerHash.constEnd(); it != end; ++it) {
- for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(),
- end2 = it.value().constEnd(); it2 != end2; ++it2) {
- delete *it2;
- }
- }
- m_glyphPointerHash.clear();
- for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(),
- end = m_glyphIntHash.constEnd(); it != end; ++it) {
- for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(),
- end2 = it.value().constEnd(); it2 != end2; ++it2) {
- delete *it2;
- }
+ for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(),
+ end = m_glyphCaches.constEnd(); it != end; ++it) {
+ delete it->cache;
}
- m_glyphIntHash.clear();
+ m_glyphCaches.clear();
qHBFreeFace(hbFace);
}
@@ -713,103 +702,30 @@ QByteArray QFontEngine::getSfntTable(uint tag) const
return table;
}
-void QFontEngine::expireGlyphCache()
-{
- if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory.
- QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst();
- // remove the value from either of our hashes
- for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) {
- QList<QFontEngineGlyphCache *> list = i.value();
- if (list.removeAll(old)) {
- if (list.isEmpty())
- m_glyphPointerHash.remove(i.key());
- else
- m_glyphPointerHash.insert(i.key(), list);
- break;
- }
- }
- for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) {
- QList<QFontEngineGlyphCache *> list = i.value();
- if (list.removeAll(old)) {
- if (list.isEmpty())
- m_glyphIntHash.remove(i.key());
- else
- m_glyphIntHash.insert(i.key(), list);
- break;
- }
- }
- delete old;
- }
-}
-
void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
{
Q_ASSERT(data);
- QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
-
- for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
- QFontEngineGlyphCache *c = *it;
- if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
- if (c == data)
- return;
- items.removeAll(c);
- delete c;
- break;
- }
- }
- items.append(data);
- m_glyphPointerHash.insert(key, items);
- m_glyphCacheQueue.append(data);
- expireGlyphCache();
-}
+ GlyphCacheEntry entry = { key, data };
+ if (m_glyphCaches.contains(entry))
+ return;
-void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data)
-{
- Q_ASSERT(data);
- QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
-
- for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
- QFontEngineGlyphCache *c = *it;
- if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
- if (c == data)
- return;
- items.removeAll(c);
- delete c;
- break;
- }
- }
- items.append(data);
- m_glyphIntHash.insert(key, items);
+ // Limit the glyph caches to 4. This covers all 90 degree rotations and limits
+ // memory use when there is continous or random rotation
+ if (m_glyphCaches.size() == 4)
+ delete m_glyphCaches.takeLast().cache;
- m_glyphCacheQueue.append(data);
- expireGlyphCache();
-}
+ m_glyphCaches.push_front(entry);
-QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const
-{
- QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
-
- for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
- QFontEngineGlyphCache *c = *it;
- if (qtransform_equals_no_translate(c->m_transform, transform)) {
- m_glyphCacheQueue.removeAll(c); // last used, move it up
- m_glyphCacheQueue.append(c);
- return c;
- }
- }
- return 0;
}
-QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const
+QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const
{
- QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
-
- for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
- QFontEngineGlyphCache *c = *it;
- if (qtransform_equals_no_translate(c->m_transform, transform)) {
- m_glyphCacheQueue.removeAll(c); // last used, move it up
- m_glyphCacheQueue.append(c);
+ for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) {
+ QFontEngineGlyphCache *c = it->cache;
+ if (key == it->context
+ && type == c->cacheType()
+ && qtransform_equals_no_translate(c->m_transform, transform)) {
return c;
}
}
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index a4e7c04..a75d70f 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -404,7 +404,9 @@ QFixed QCoreTextFontEngine::ascent() const
}
QFixed QCoreTextFontEngine::descent() const
{
- return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
+ // subtract a pixel to even out the historical +1 in QFontMetrics::height().
+ // Fix in Qt 5.
+ return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1;
}
QFixed QCoreTextFontEngine::leading() const
{
@@ -1406,7 +1408,9 @@ QFixed QFontEngineMac::ascent() const
QFixed QFontEngineMac::descent() const
{
- return m_descent;
+ // subtract a pixel to even out the historical +1 in QFontMetrics::height().
+ // Fix in Qt 5.
+ return m_descent - 1;
}
QFixed QFontEngineMac::leading() const
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 728c344..a9883b4 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -56,6 +56,7 @@
#include "QtCore/qglobal.h"
#include "QtCore/qatomic.h"
#include <QtCore/qvarlengtharray.h>
+#include <QtCore/QLinkedList>
#include "private/qtextengine_p.h"
#include "private/qfont_p.h"
@@ -219,9 +220,7 @@ public:
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
void setGlyphCache(void *key, QFontEngineGlyphCache *data);
- void setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data);
- QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform) const;
- QFontEngineGlyphCache *glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const;
+ QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode);
@@ -254,12 +253,13 @@ protected:
static const QVector<QRgb> &grayPalette();
private:
- /// remove old entries from the glyph cache. Helper method for the setGlyphCache ones.
- void expireGlyphCache();
+ struct GlyphCacheEntry {
+ void *context;
+ QFontEngineGlyphCache *cache;
+ bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; }
+ };
- GlyphPointerHash m_glyphPointerHash;
- GlyphIntHash m_glyphIntHash;
- mutable QList<QFontEngineGlyphCache*> m_glyphCacheQueue;
+ mutable QLinkedList<GlyphCacheEntry> m_glyphCaches;
};
inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2)
diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h
index e04f4ac..c6112ba 100644
--- a/src/gui/text/qfontengineglyphcache_p.h
+++ b/src/gui/text/qfontengineglyphcache_p.h
@@ -75,17 +75,20 @@ QT_BEGIN_NAMESPACE
class QFontEngineGlyphCache
{
public:
- QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { }
-
enum Type {
Raster_RGBMask,
Raster_A8,
Raster_Mono
};
+ QFontEngineGlyphCache(const QTransform &matrix, Type type) : m_transform(matrix), m_type(type) { }
+
virtual ~QFontEngineGlyphCache() { }
+ Type cacheType() const { return m_type; }
+
QTransform m_transform;
+ QFontEngineGlyphCache::Type m_type;
};
typedef QHash<void *, QList<QFontEngineGlyphCache *> > GlyphPointerHash;
typedef QHash<int, QList<QFontEngineGlyphCache *> > GlyphIntHash;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index f96f66b..f523226 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1938,7 +1938,11 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e)
emit q->updateRequest(q->selectionRect());
if (e->gotFocus()) {
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) {
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
#endif
cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
if (interactionFlags & Qt::TextEditable) {
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 18e1ffc..b015198 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -870,6 +870,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
undoEnabled = false;
beginEditBlock();
+ int editPos = -1;
while (1) {
if (undo)
--undoState;
@@ -881,11 +882,13 @@ int QTextDocumentPrivate::undoRedo(bool undo)
remove(c.pos, c.length, (QTextUndoCommand::Operation)c.operation);
PMDEBUG(" erase: from %d, length %d", c.pos, c.length);
c.command = QTextUndoCommand::Removed;
+ editPos = c.pos;
break;
case QTextUndoCommand::Removed:
PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos);
insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation);
c.command = QTextUndoCommand::Inserted;
+ editPos = c.pos + c.length;
break;
case QTextUndoCommand::BlockInserted:
case QTextUndoCommand::BlockAdded:
@@ -895,6 +898,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
c.command = QTextUndoCommand::BlockRemoved;
else
c.command = QTextUndoCommand::BlockDeleted;
+ editPos = c.pos;
break;
case QTextUndoCommand::BlockRemoved:
case QTextUndoCommand::BlockDeleted:
@@ -905,6 +909,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
c.command = QTextUndoCommand::BlockInserted;
else
c.command = QTextUndoCommand::BlockAdded;
+ editPos = c.pos + 1;
break;
case QTextUndoCommand::CharFormatChanged: {
resetBlockRevision = -1; // ## TODO
@@ -915,6 +920,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
int oldFormat = it.value()->format;
setCharFormat(c.pos, c.length, formats.charFormat(c.format));
c.format = oldFormat;
+ editPos = c.pos + c.length;
break;
}
case QTextUndoCommand::BlockFormatChanged: {
@@ -937,6 +943,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
group->blockFormatChanged(it);
}
documentChange(it.position(), it.length());
+ editPos = -1;
break;
}
case QTextUndoCommand::GroupFormatChange: {
@@ -946,6 +953,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
int oldFormat = formats.objectFormatIndex(c.objectIndex);
changeObjectFormat(object, c.format);
c.format = oldFormat;
+ editPos = -1;
break;
}
case QTextUndoCommand::Custom:
@@ -954,6 +962,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
c.custom->undo();
else
c.custom->redo();
+ editPos = -1;
break;
default:
Q_ASSERT(false);
@@ -979,8 +988,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
break;
}
undoEnabled = true;
- int editPos = -1;
- if (docChangeFrom >= 0) {
+ if (editPos < 0 && docChangeFrom >= 0) {
editPos = qMin(docChangeFrom + docChangeLength, length() - 1);
}
endEditBlock();
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 1890d56..c6932de 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -41,7 +41,7 @@
// This flag changes the implementation to use S60 CDcoumentHandler
// instead of apparch when opening the files
-#undef USE_DOCUMENTHANDLER
+#define USE_DOCUMENTHANDLER
#include <qcoreapplication.h>
#include <qdir.h>
@@ -58,12 +58,14 @@
#include <rsendasmessage.h> // RSendAsMessage
#ifdef Q_WS_S60
-# include <pathinfo.h> // PathInfo
+# include <pathinfo.h> // PathInfo
# ifdef USE_DOCUMENTHANDLER
-# include <documenthandler.h> // CDocumentHandler
+# include <documenthandler.h> // CDocumentHandler
+# include <aknserverapp.h>
# endif
-#elif defined(USE_DOCUMENTHANDLER)
-# error CDocumentHandler requires support for S60
+#else
+# warning CDocumentHandler requires support for S60
+# undef USE_DOCUMENTHANDLER // Fallback to RApaLsSession based implementation
#endif
QT_BEGIN_NAMESPACE
@@ -95,6 +97,42 @@ private:
R* mPtr;
};
+#ifdef USE_DOCUMENTHANDLER
+class QS60DocumentHandler : public MAknServerAppExitObserver
+{
+public:
+ QS60DocumentHandler() :docHandler(0) {}
+
+ ~QS60DocumentHandler() {
+ delete docHandler;
+ }
+
+ CDocumentHandler& documentHandler() {
+ // In case user calls openUrl twice subsequently, before the first embedded app is closed
+ // we use the same CDocumentHandler instance. Using same instance makes sure the first
+ // launched embedded app is closed and latter one gets embedded to our app.
+ // Using different instance would help only theoretically since user cannot interact with
+ // several embedded apps at the same time.
+ if(!docHandler) {
+ QT_TRAP_THROWING(docHandler = CDocumentHandler::NewL());
+ docHandler->SetExitObserver(this);
+ }
+ return *docHandler;
+ }
+
+private: // From MAknServerAppExitObserver
+ void HandleServerAppExit(TInt /*aReason*/) {
+ delete docHandler;
+ docHandler = 0;
+ }
+
+private:
+ CDocumentHandler* docHandler;
+};
+Q_GLOBAL_STATIC(QS60DocumentHandler, qt_s60_documenthandler);
+#endif
+
+
static void handleMailtoSchemeLX(const QUrl &url)
{
// this function has many intermingled leaves and throws. Qt and Symbian objects do not have
@@ -264,21 +302,9 @@ static void openDocumentL(const TDesC& aUrl)
CleanupStack::PopAndDestroy(); // appArcSession
#else
// This is an alternative way to launch app associated to MIME type
- // CDocumentHandler would support opening apps in embedded mode,
- // but our Qt application window group seems to always get switched on top of embedded one
- // -> Cannot use menus etc of embedded app -> used
-
- CDocumentHandler* docHandler = CDocumentHandler::NewLC();
+ // CDocumentHandler also supports opening apps in embedded mode.
TDataType temp;
- //Standalone file opening fails for some file-types at least in S60 3.1 emulator
- //For example .txt file fails with KErrAlreadyInUse and music files with KERN-EXEC 0
- //Workaround is to use OpenFileEmbeddedL
- //docHandler->OpenFileL(aUrl, temp);
-
- // Opening file with CDocumentHandler will leave if file does not exist
- // Leave is trapped in openDocument and false returned to user.
- docHandler->OpenFileEmbeddedL(aUrl, temp);
- CleanupStack::PopAndDestroy(docHandler);
+ qt_s60_documenthandler()->documentHandler().OpenFileEmbeddedL(aUrl, temp);
#endif
}
@@ -349,7 +375,7 @@ QString QDesktopServices::storageLocation(StandardLocation type)
case DesktopLocation:
qWarning("No desktop concept in Symbian OS");
// But lets still use some feasible default
- path.Append(writableDataRoot());
+ path.Append(writableDataRoot());
break;
case DocumentsLocation:
path.Append(writableDataRoot());
@@ -380,7 +406,7 @@ QString QDesktopServices::storageLocation(StandardLocation type)
#endif
break;
case TempLocation:
- return QDir::tempPath();
+ return QDir::tempPath();
break;
case HomeLocation:
path.Append(writableDataRoot());
@@ -394,10 +420,10 @@ QString QDesktopServices::storageLocation(StandardLocation type)
CEikonEnv::Static()->FsSession().PrivatePath(path);
path.Insert(0, writableExeDrive().Name());
path.Append(KCacheSubDir);
- break;
+ break;
default:
// Lets use feasible default
- path.Append(writableDataRoot());
+ path.Append(writableDataRoot());
break;
}
diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp
index c6ea00f..6f2b501 100644
--- a/src/gui/util/qsystemtrayicon.cpp
+++ b/src/gui/util/qsystemtrayicon.cpp
@@ -380,6 +380,9 @@ bool QSystemTrayIcon::supportsMessages()
On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
when the application has focus.
+ On Mac OS X, the Growl notification system must be installed for this function to
+ display messages.
+
\sa show() supportsMessages()
*/
void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm
index b74ca85..93295a7 100644
--- a/src/gui/util/qsystemtrayicon_mac.mm
+++ b/src/gui/util/qsystemtrayicon_mac.mm
@@ -314,8 +314,22 @@ QT_END_NAMESPACE
{
Q_UNUSED(notification);
down = NO;
+
+ if( ![self icon]->icon().isNull() ) {
+#ifndef QT_MAC_USE_COCOA
+ const short scale = GetMBarHeight()-4;
+#else
+ CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
+ const short scale = hgt - 4;
+#endif
+ NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale))));
+ [self setImage: nsimage];
+ [nsimage release];
+ }
+
if([self icon]->contextMenu())
[self icon]->contextMenu()->hide();
+
[self setNeedsDisplay:YES];
}
@@ -327,6 +341,20 @@ QT_END_NAMESPACE
[self icon]->contextMenu()->hide();
[self setNeedsDisplay:YES];
+#ifndef QT_MAC_USE_COCOA
+ const short scale = GetMBarHeight()-4;
+#else
+ CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
+ const short scale = hgt - 4;
+#endif
+
+ if( down && ![self icon]->icon().isNull() ) {
+ NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale), QIcon::Selected)));
+ [self setImage: nsaltimage];
+ [nsaltimage release];
+ }
+
+
if (down)
[parent triggerSelector:self];
else if ((clickCount%2))
diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
index 86de366..029a259 100644
--- a/src/gui/util/qsystemtrayicon_p.h
+++ b/src/gui/util/qsystemtrayicon_p.h
@@ -94,6 +94,7 @@ public:
class QBalloonTip : public QWidget
{
+ Q_OBJECT
public:
static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
const QString& msg, QSystemTrayIcon *trayIcon,
diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp
index 362be5b..474555b 100644
--- a/src/gui/util/qsystemtrayicon_win.cpp
+++ b/src/gui/util/qsystemtrayicon_win.cpp
@@ -83,7 +83,11 @@ struct Q_NOTIFYICONIDENTIFIER {
GUID guidItem;
};
+#define Q_MSGFLT_ALLOW 1
+
typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation);
+typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag);
+typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct);
class QSystemTrayIconSys : QWidget
{
@@ -143,6 +147,23 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
if (!MYWM_TASKBARCREATED) {
MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
}
+
+ // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows Vista and higher
+ static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx =
+ (PtrChangeWindowMessageFilterEx)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx");
+
+ if (pChangeWindowMessageFilterEx) {
+ // Call the safer ChangeWindowMessageFilterEx API if available
+ pChangeWindowMessageFilterEx(winId(), MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0);
+ } else {
+ static PtrChangeWindowMessageFilter pChangeWindowMessageFilter =
+ (PtrChangeWindowMessageFilter)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter");
+
+ if (pChangeWindowMessageFilter) {
+ // Call the deprecated ChangeWindowMessageFilter API otherwise
+ pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW);
+ }
+ }
}
QSystemTrayIconSys::~QSystemTrayIconSys()
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 35639b7..3cf4e94 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -294,7 +294,9 @@ void QAbstractScrollAreaPrivate::init()
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
+#ifndef Q_WS_MAC
viewport->grabGesture(Qt::PanGesture);
+#endif
}
#ifdef Q_WS_WIN
@@ -543,7 +545,9 @@ void QAbstractScrollArea::setViewport(QWidget *widget)
d->viewport->setParent(this);
d->viewport->setFocusProxy(this);
d->viewport->installEventFilter(d->viewportFilter.data());
+#ifndef Q_WS_MAC
d->viewport->grabGesture(Qt::PanGesture);
+#endif
d->layoutChildren();
if (isVisible())
d->viewport->show();
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp
index a18af4f..e26d5c3 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/gui/widgets/qabstractspinbox.cpp
@@ -65,6 +65,11 @@
#include <limits.h>
#endif
+#if defined(Q_OS_SYMBIAN)
+#include <W32STD.H>
+#include <private/qt_s60_p.h>
+#endif
+
//#define QABSTRACTSPINBOX_QSBDEBUG
#ifdef QABSTRACTSPINBOX_QSBDEBUG
# define QASBDEBUG qDebug
@@ -939,10 +944,12 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
d->edit->setCursorPosition(d->prefix.size());
int steps = 1;
+ bool isPgUpOrDown = false;
switch (event->key()) {
case Qt::Key_PageUp:
case Qt::Key_PageDown:
steps *= 10;
+ isPgUpOrDown = true;
case Qt::Key_Up:
case Qt::Key_Down: {
#ifdef QT_KEYPAD_NAVIGATION
@@ -964,7 +971,13 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
d->buttonState = (Keyboard | (up ? Up : Down));
}
- stepBy(steps);
+ if (d->spinClickTimerId == -1)
+ stepBy(steps);
+ if(event->isAutoRepeat() && !isPgUpOrDown) {
+ if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) {
+ d->updateState(up, true);
+ }
+ }
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
#endif
@@ -1061,8 +1074,7 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QAbstractSpinBox);
- if (d->buttonState & Keyboard && !event->isAutoRepeat()
- && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
+ if (d->buttonState & Keyboard && !event->isAutoRepeat()) {
d->reset();
} else {
d->edit->event(event);
@@ -1148,6 +1160,34 @@ void QAbstractSpinBox::hideEvent(QHideEvent *event)
QWidget::hideEvent(event);
}
+
+/*!
+ \internal
+
+ Used when acceleration is turned on. We need to get the
+ keyboard auto repeat rate from OS. This value is used as
+ argument when starting acceleration related timers.
+
+ Every platform should, either, use native calls to obtain
+ the value or hard code some reasonable rate.
+
+ Remember that time value should be given in msecs.
+*/
+static int getKeyboardAutoRepeatRate() {
+ int ret = 30;
+#if defined(Q_OS_SYMBIAN)
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ S60->wsSession().GetKeyboardRepeatRate(initialTime, time);
+ ret = time.Int() / 1000; // msecs
+#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ DWORD time;
+ if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE)
+ ret = static_cast<int>(1000 / static_cast<int>(time)); // msecs
+#endif
+ return ret; // msecs
+}
+
/*!
\reimp
*/
@@ -1160,14 +1200,17 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
if (event->timerId() == d->spinClickThresholdTimerId) {
killTimer(d->spinClickThresholdTimerId);
d->spinClickThresholdTimerId = -1;
- d->spinClickTimerId = startTimer(d->spinClickTimerInterval);
+ d->effectiveSpinRepeatRate = d->buttonState & Keyboard
+ ? getKeyboardAutoRepeatRate()
+ : d->spinClickTimerInterval;
+ d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
doStep = true;
} else if (event->timerId() == d->spinClickTimerId) {
if (d->accelerate) {
- d->acceleration = d->acceleration + (int)(d->spinClickTimerInterval * 0.05);
- if (d->spinClickTimerInterval - d->acceleration >= 10) {
+ d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05);
+ if (d->effectiveSpinRepeatRate - d->acceleration >= 10) {
killTimer(d->spinClickTimerId);
- d->spinClickTimerId = startTimer(d->spinClickTimerInterval - d->acceleration);
+ d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration);
}
}
doStep = true;
@@ -1308,8 +1351,8 @@ void QAbstractSpinBox::mouseReleaseEvent(QMouseEvent *event)
QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
: edit(0), type(QVariant::Invalid), spinClickTimerId(-1),
spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1),
- buttonState(None), cachedText(QLatin1String("\x01")), cachedState(QValidator::Invalid),
- pendingEmit(false), readOnly(false), wrapping(false),
+ effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")),
+ cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0)
@@ -1554,7 +1597,7 @@ void QAbstractSpinBoxPrivate::reset()
Updates the state of the spinbox.
*/
-void QAbstractSpinBoxPrivate::updateState(bool up)
+void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */)
{
Q_Q(QAbstractSpinBox);
if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
@@ -1563,7 +1606,7 @@ void QAbstractSpinBoxPrivate::updateState(bool up)
if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
: QAbstractSpinBox::StepDownEnabled))) {
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
- buttonState = (up ? (Mouse | Up) : (Mouse | Down));
+ buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
q->stepBy(up ? 1 : -1);
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
@@ -1856,8 +1899,10 @@ QValidator::State QSpinBoxValidator::validate(QString &input, int &pos) const
if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText)
return QValidator::Acceptable;
- if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix))
+ if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
input.prepend(dptr->prefix);
+ pos += dptr->prefix.length();
+ }
if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
input.append(dptr->suffix);
diff --git a/src/gui/widgets/qabstractspinbox_p.h b/src/gui/widgets/qabstractspinbox_p.h
index 3020cbc..55f94d7 100644
--- a/src/gui/widgets/qabstractspinbox_p.h
+++ b/src/gui/widgets/qabstractspinbox_p.h
@@ -98,7 +98,7 @@ public:
void init();
void reset();
- void updateState(bool up);
+ void updateState(bool up, bool fromKeyboard = false);
QString stripped(const QString &text, int *pos = 0) const;
bool specialValue() const;
virtual QVariant getZeroVariant() const;
@@ -129,6 +129,7 @@ public:
QVariant value, minimum, maximum, singleStep;
QVariant::Type type;
int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval;
+ int effectiveSpinRepeatRate;
uint buttonState;
mutable QString cachedText;
mutable QVariant cachedValue;
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index bd1d8ba..b7dd20c 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -931,7 +931,10 @@ void QComboBoxPrivate::init()
QSizePolicy::ComboBox));
setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
q->setModel(new QStandardItemModel(0, 1, q));
- q->setAttribute(Qt::WA_InputMethodEnabled);
+ if (!q->isEditable())
+ q->setAttribute(Qt::WA_InputMethodEnabled, false);
+ else
+ q->setAttribute(Qt::WA_InputMethodEnabled);
}
QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer()
diff --git a/src/gui/widgets/qdial.cpp b/src/gui/widgets/qdial.cpp
index 95e6ed5..dc02c02 100644
--- a/src/gui/widgets/qdial.cpp
+++ b/src/gui/widgets/qdial.cpp
@@ -59,6 +59,7 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -135,7 +136,7 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const
Q_Q(const QDial);
double yy = (double)q->height()/2.0 - p.y();
double xx = (double)p.x() - q->width()/2.0;
- double a = (xx || yy) ? atan2(yy, xx) : 0;
+ double a = (xx || yy) ? qAtan2(yy, xx) : 0;
if (a < Q_PI / -2)
a = a + Q_PI * 2;
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 0e859f1..f2ef941 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -46,6 +46,7 @@
#include <QtGui/qdialog.h>
#include <QtGui/qapplication.h>
#include <QtGui/private/qwidget_p.h>
+#include <QtGui/qaction.h>
#include "qdialogbuttonbox.h"
@@ -259,6 +260,31 @@ static const int layouts[2][5][14] =
}
};
+class QDialogButtonEnabledProxy : public QObject
+{
+public:
+ QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg)
+ {
+ source->installEventFilter(this);
+ target->setEnabled(source->isEnabled());
+ }
+ ~QDialogButtonEnabledProxy()
+ {
+ source->removeEventFilter(this);
+ }
+ bool eventFilter(QObject *object, QEvent *event)
+ {
+ if (object == source && event->type() == QEvent::EnabledChange) {
+ target->setEnabled(source->isEnabled());
+ }
+ return false;
+ };
+private:
+ QWidget *source;
+ QAction *target;
+};
+
+
class QDialogButtonBoxPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QDialogButtonBox)
@@ -548,7 +574,9 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo
QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
buttonLists[role].append(button);
#ifdef QT_SOFTKEYS_ENABLED
- softKeyActions.insert(button, createSoftKey(button, role));
+ QAction *action = createSoftKey(button, role);
+ softKeyActions.insert(button, action);
+ new QDialogButtonEnabledProxy(action, button, action);
#endif
if (doLayout)
layoutButtons();
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 0a26a77..cf82da0 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -1303,9 +1303,9 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path)
index = -index - 1;
if (index >= item_list.count())
return this;
- if (path.count() == 1 || item_list.at(index).subinfo == 0)
+ if (path.count() == 1 || item_list[index].subinfo == 0)
return this;
- return item_list.at(index).subinfo->info(path.mid(1));
+ return item_list[index].subinfo->info(path.mid(1));
}
QRect QDockAreaLayoutInfo::itemRect(int index) const
diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h
index e65637d..b7162cd 100644
--- a/src/gui/widgets/qlcdnumber.h
+++ b/src/gui/widgets/qlcdnumber.h
@@ -82,9 +82,10 @@ public:
};
bool smallDecimalPoint() const;
-
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numDigits() const;
QT_DEPRECATED void setNumDigits(int nDigits);
+#endif
int digitCount() const;
void setDigitCount(int nDigits);
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 87975c3..117c550 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -1586,16 +1586,16 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
}
#endif //QT_NO_CLIPBOARD
- else if (event == QKeySequence::MoveToStartOfLine) {
+ else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) {
home(0);
}
- else if (event == QKeySequence::MoveToEndOfLine) {
+ else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) {
end(0);
}
- else if (event == QKeySequence::SelectStartOfLine) {
+ else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) {
home(1);
}
- else if (event == QKeySequence::SelectEndOfLine) {
+ else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) {
end(1);
}
else if (event == QKeySequence::MoveToNextChar) {
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 785b2bd..573b2b5 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -383,6 +383,38 @@ void QLineEdit::setText(const QString& text)
d->control->setText(text);
}
+// ### Qt 4.7: remove this #if guard
+#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
+/*!
+ \since 4.7
+
+ \property QLineEdit::placeholderText
+ \brief the line edit's placeholder text
+
+ Setting this property makes the line edit display a grayed-out
+ placeholder text as long as the text() is empty and the widget doesn't
+ have focus.
+
+ By default, this property contains an empty string.
+
+ \sa text()
+*/
+QString QLineEdit::placeholderText() const
+{
+ Q_D(const QLineEdit);
+ return d->placeholderText;
+}
+
+void QLineEdit::setPlaceholderText(const QString& placeholderText)
+{
+ Q_D(QLineEdit);
+ if (d->placeholderText != placeholderText) {
+ d->placeholderText = placeholderText;
+ if (!hasFocus())
+ update();
+ }
+}
+#endif
/*!
\property QLineEdit::displayText
@@ -1413,6 +1445,16 @@ bool QLineEdit::event(QEvent * e)
d->control->processEvent(e);
} else if (e->type() == QEvent::KeyRelease) {
d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ } else if (e->type() == QEvent::Show) {
+ //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
+ if (hasFocus()) {
+ d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
+ || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
+ d->setCursorVisible(true);
+ }
}
#ifdef QT_KEYPAD_NAVIGATION
@@ -1517,7 +1559,7 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
}
#endif
- if (!isReadOnly())
+ if (!isReadOnly() && rect().contains(e->pos()))
d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -1719,7 +1761,11 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
d->clickCausedFocus = 1;
}
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason)){
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
#endif
d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
QStyleOptionFrameV2 opt;
@@ -1829,6 +1875,18 @@ void QLineEdit::paintEvent(QPaintEvent *)
}
QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
+ if (d->control->text().isEmpty()) {
+ if (!hasFocus() && !d->placeholderText.isEmpty()) {
+ QColor col = pal.text().color();
+ col.setAlpha(128);
+ QPen oldpen = p.pen();
+ p.setPen(col);
+ p.drawText(lineRect, va, d->placeholderText);
+ p.setPen(oldpen);
+ return;
+ }
+ }
+
int cix = qRound(d->control->cursorToX());
// horizontal scrolling. d->hscroll is the left indent from the beginning
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index ac918c7..3f159f6 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -83,6 +83,10 @@ class Q_GUI_EXPORT QLineEdit : public QWidget
Q_PROPERTY(bool undoAvailable READ isUndoAvailable)
Q_PROPERTY(bool redoAvailable READ isRedoAvailable)
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
+// ### Qt 4.7: remove this #if guard
+#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
+ Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
+#endif
public:
explicit QLineEdit(QWidget* parent=0);
@@ -98,6 +102,12 @@ public:
QString displayText() const;
+// ### Qt 4.7: remove this #if guard
+#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5)
+ QString placeholderText() const;
+ void setPlaceholderText(const QString &);
+#endif
+
int maxLength() const;
void setMaxLength(int);
@@ -278,6 +288,7 @@ private:
#ifdef QT_KEYPAD_NAVIGATION
Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
};
#endif // QT_NO_LINEEDIT
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
index d03c003..c18ca25 100644
--- a/src/gui/widgets/qlineedit_p.cpp
+++ b/src/gui/widgets/qlineedit_p.cpp
@@ -103,12 +103,12 @@ void QLineEditPrivate::_q_handleWindowActivate()
void QLineEditPrivate::_q_textEdited(const QString &text)
{
Q_Q(QLineEdit);
+ emit q->textEdited(text);
#ifndef QT_NO_COMPLETER
- if (control->completer() &&
- control->completer()->completionMode() != QCompleter::InlineCompletion)
+ if (control->completer()
+ && control->completer()->completionMode() != QCompleter::InlineCompletion)
control->complete(-1); // update the popup on cut/paste/del
#endif
- emit q->textEdited(text);
}
void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
@@ -126,6 +126,21 @@ void QLineEditPrivate::_q_editFocusChange(bool e)
}
#endif
+void QLineEditPrivate::_q_selectionChanged()
+{
+ Q_Q(QLineEdit);
+ if (control->preeditAreaText().isEmpty()) {
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ bool showCursor = control->hasSelectedText() ?
+ q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q):
+ true;
+ setCursorVisible(showCursor);
+ }
+
+ emit q->selectionChanged();
+}
+
void QLineEditPrivate::init(const QString& txt)
{
Q_Q(QLineEdit);
@@ -138,7 +153,7 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
q, SLOT(_q_cursorPositionChanged(int,int)));
QObject::connect(control, SIGNAL(selectionChanged()),
- q, SIGNAL(selectionChanged()));
+ q, SLOT(_q_selectionChanged()));
QObject::connect(control, SIGNAL(accepted()),
q, SIGNAL(returnPressed()));
QObject::connect(control, SIGNAL(editingFinished()),
@@ -149,6 +164,9 @@ void QLineEditPrivate::init(const QString& txt)
#endif
QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
q, SLOT(updateMicroFocus()));
+
+ QObject::connect(control, SIGNAL(textChanged(const QString &)),
+ q, SLOT(updateMicroFocus()));
// for now, going completely overboard with updates.
QObject::connect(control, SIGNAL(selectionChanged()),
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
index 244d2be..f13dce2 100644
--- a/src/gui/widgets/qlineedit_p.h
+++ b/src/gui/widgets/qlineedit_p.h
@@ -128,7 +128,7 @@ public:
#ifdef QT_KEYPAD_NAVIGATION
void _q_editFocusChange(bool);
#endif
-
+ void _q_selectionChanged();
#ifndef QT_NO_COMPLETER
void _q_completionHighlighted(QString);
#endif
@@ -142,6 +142,8 @@ public:
int topTextMargin;
int rightTextMargin;
int bottomTextMargin;
+
+ QString placeholderText;
};
#endif // QT_NO_LINEEDIT
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 8d8ffa7..6d50678 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -463,9 +463,6 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar)
NSToolbarItem *item = static_cast<NSToolbarItem *>(it.key());
[[qt_mac_window_for(layoutState.mainWindow->window()) toolbar]
removeItemAtIndex:toolbarItemsCopy.indexOf(item)];
- // In Carbon this hash and list gets emptied via events. In Cocoa, we have to do it ourselves here.
- it = unifiedToolbarHash.erase(it);
- qtoolbarsInUnifiedToolbarList.removeAll(toolbar);
#endif
break;
}
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 2e27226..ec9683d 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -65,6 +65,8 @@
#include "qmenubar_p.h"
#include "qwidgetaction.h"
#include "qtoolbutton.h"
+#include "qpushbutton.h"
+#include <private/qpushbutton_p.h>
#include <private/qaction_p.h>
#include <private/qsoftkeymanager_p.h>
#ifdef QT3_SUPPORT
@@ -417,12 +419,7 @@ void QMenuPrivate::hideUpToMenuBar()
hideMenu(m, fadeMenus);
if (!fadeMenus) // Mac doesn't clear the action until after hidden.
m->d_func()->setCurrentAction(0);
- } else {
-#ifndef QT_NO_TOOLBUTTON
- if (qobject_cast<QToolButton*>(caused) == 0)
-#endif
- qWarning("QMenu: Internal error");
- caused = 0;
+ } else { caused = 0;
}
}
#if defined(Q_WS_MAC)
@@ -1825,8 +1822,15 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
ensurePolished(); // Get the right font
emit aboutToShow();
+ const bool actionListChanged = d->itemsDirty;
d->updateActionRects();
- QPoint pos = p;
+ QPoint pos;
+ QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);
+ if (actionListChanged && causedButton)
+ pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
+ else
+ pos = p;
+
QSize size = sizeHint();
QRect screen;
#ifndef QT_NO_GRAPHICSVIEW
@@ -2302,22 +2306,9 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e)
if (action->menu())
action->menu()->d_func()->setFirstActionActive();
else {
-#if defined(Q_WS_WIN) && !defined(QT_NO_MENUBAR)
+#if defined(Q_WS_WIN)
//On Windows only context menus can be activated with the right button
- bool isContextMenu = true;
- const QWidget *cause = d->causedPopup.widget;
- while (cause) {
- //if the popup was caused by either QMenuBar or a QToolButton, it is not a context menu
- if (qobject_cast<const QMenuBar *>(cause) || qobject_cast<const QToolButton *>(cause)) {
- isContextMenu = false;
- break;
- } else if (const QMenu *menu = qobject_cast<const QMenu *>(cause)) {
- cause = menu->d_func()->causedPopup.widget;
- } else {
- break;
- }
- }
- if (e->button() == Qt::LeftButton || isContextMenu)
+ if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
#endif
d->activateAction(action, QAction::Trigger);
}
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 5757885..93017f5 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -182,6 +182,7 @@ public:
}
void init();
+ static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
int scrollerHeight() const;
//item calculations
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index c7759e8..a3624d6 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -684,8 +684,12 @@ void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceC
qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
+ QTextBlock previousVisibleBlock = block;
while (h < height && block.previous().isValid()) {
- block = block.previous();
+ previousVisibleBlock = block;
+ do {
+ block = block.previous();
+ } while (!block.isVisible() && block.previous().isValid());
h += q->blockBoundingRect(block).height();
}
@@ -699,8 +703,8 @@ void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceC
++l;
}
- if (block.next().isValid() && l >= lineCount) {
- block = block.next();
+ if (l >= lineCount) {
+ block = previousVisibleBlock;
l = 0;
}
setTopBlock(block.blockNumber(), l);
@@ -761,6 +765,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
// set a null page size initially to avoid any relayouting until the textedit
// is shown. relayoutDocument() will take care of setting the page size to the
@@ -1802,6 +1807,9 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
QTextBlock block = firstVisibleBlock();
qreal maximumWidth = document()->documentLayout()->documentSize().width();
+ // Set a brush origin so that the WaveUnderline knows where the wave started
+ painter.setBrushOrigin(offset);
+
// keep right margin clean from full-width selection
int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
- document()->documentMargin();
@@ -1966,7 +1974,7 @@ void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->ensureCursorVisible();
}
- if (!isReadOnly())
+ if (!isReadOnly() && rect().contains(e->pos()))
d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h
index 08e596d..d8504de 100644
--- a/src/gui/widgets/qprintpreviewwidget.h
+++ b/src/gui/widgets/qprintpreviewwidget.h
@@ -82,7 +82,9 @@ public:
ViewMode viewMode() const;
ZoomMode zoomMode() const;
int currentPage() const;
+#ifdef QT_DEPRECATED
QT_DEPRECATED int numPages() const;
+#endif
int pageCount() const;
void setVisible(bool visible);
diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp
index eb34336..849bc43 100644
--- a/src/gui/widgets/qpushbutton.cpp
+++ b/src/gui/widgets/qpushbutton.cpp
@@ -63,6 +63,7 @@
#include "qaccessible.h"
#endif
+#include "private/qmenu_p.h"
#include "private/qpushbutton_p.h"
QT_BEGIN_NAMESPACE
@@ -575,12 +576,33 @@ void QPushButtonPrivate::_q_popupPressed()
return;
menu->setNoReplayFor(q);
+
+ QPoint menuPos = adjustedMenuPosition();
+
+ QPointer<QPushButton> guard(q);
+ QMenuPrivate::get(menu)->causedPopup.widget = guard;
+
+ //Because of a delay in menu effects, we must keep track of the
+ //menu visibility to avoid flicker on button release
+ menuOpen = true;
+ menu->exec(menuPos);
+ if (guard) {
+ menuOpen = false;
+ q->setDown(false);
+ }
+}
+
+QPoint QPushButtonPrivate::adjustedMenuPosition()
+{
+ Q_Q(QPushButton);
+
bool horizontal = true;
#if !defined(QT_NO_TOOLBAR)
QToolBar *tb = qobject_cast<QToolBar*>(parent);
if (tb && tb->orientation() == Qt::Vertical)
horizontal = false;
#endif
+
QWidgetItem item(q);
QRect rect = item.geometry();
rect.setRect(rect.x() - q->x(), rect.y() - q->y(), rect.width(), rect.height());
@@ -603,17 +625,10 @@ void QPushButtonPrivate::_q_popupPressed()
else
x -= menuSize.width();
}
- QPointer<QPushButton> guard(q);
- //Because of a delay in menu effects, we must keep track of the
- //menu visibility to avoid flicker on button release
- menuOpen = true;
- menu->exec(QPoint(x, y));
- if (guard) {
- menuOpen = false;
- q->setDown(false);
- }
+ return QPoint(x,y);
}
+
#endif // QT_NO_MENU
void QPushButtonPrivate::resetLayoutItemMargins()
diff --git a/src/gui/widgets/qpushbutton_p.h b/src/gui/widgets/qpushbutton_p.h
index f448027..2510e05 100644
--- a/src/gui/widgets/qpushbutton_p.h
+++ b/src/gui/widgets/qpushbutton_p.h
@@ -68,6 +68,10 @@ public:
defaultButton(false), flat(false), menuOpen(false), lastAutoDefault(false) {}
inline void init() { resetLayoutItemMargins(); }
+ static QPushButtonPrivate* get(QPushButton *b) { return b->d_func(); }
+#ifndef QT_NO_MENU
+ QPoint adjustedMenuPosition();
+#endif
void resetLayoutItemMargins();
void _q_popupPressed();
QDialog *dialogParent() const;
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index 1c49ef0..5d8f134 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -158,6 +158,8 @@ void QTextEditPrivate::init(const QString &html)
QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+
QTextDocument *doc = control->document();
// set a null page size initially to avoid any relayouting until the textedit
// is shown. relayoutDocument() will take care of setting the page size to the
@@ -1578,7 +1580,7 @@ void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->autoScrollTimer.stop();
ensureCursorVisible();
}
- if (!isReadOnly())
+ if (!isReadOnly() && rect().contains(e->pos()))
d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index 58a3d28..c0ca015 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -396,10 +396,10 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
void QToolBarPrivate::unplug(const QRect &_r)
{
Q_Q(QToolBar);
- layout->setExpanded(false);
QRect r = _r;
r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
setWindowState(true, true, r);
+ layout->setExpanded(false);
}
void QToolBarPrivate::plug(const QRect &r)
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp
index c329305..b83026b 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/gui/widgets/qtoolbararealayout.cpp
@@ -598,16 +598,21 @@ int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const
{
switch (dockPos) {
case QInternal::LeftDock:
- return pos.x() - rect.right();
+ if (pos.y() < rect.bottom())
+ return pos.x() - rect.right();
case QInternal::RightDock:
- return rect.left() - pos.x();
+ if (pos.y() < rect.bottom())
+ return rect.left() - pos.x();
case QInternal::TopDock:
- return pos.y() - rect.bottom();
+ if (pos.x() < rect.right())
+ return pos.y() - rect.bottom();
case QInternal::BottomDock:
- return rect.top() - pos.y();
+ if (pos.x() < rect.right())
+ return rect.top() - pos.y();
default:
- return -1;
+ break;
}
+ return -1;
}
/******************************************************************************
diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp
index 0afe5d8..93429e4 100644
--- a/src/gui/widgets/qtoolbarlayout.cpp
+++ b/src/gui/widgets/qtoolbarlayout.cpp
@@ -654,6 +654,7 @@ void QToolBarLayout::setExpanded(bool exp)
if (!tb)
return;
if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
+ animating = !tb->isWindow() && win->isAnimated();
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
if (expanded) {
tb->raise();
@@ -664,7 +665,7 @@ void QToolBarLayout::setExpanded(bool exp)
layoutActions(rect.size());
}
}
- layout->layoutState.toolBarAreaLayout.apply(win->isAnimated());
+ layout->layoutState.toolBarAreaLayout.apply(animating);
}
}
diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri
index c445941..625b871c 100644
--- a/src/multimedia/audio/audio.pri
+++ b/src/multimedia/audio/audio.pri
@@ -17,6 +17,8 @@ SOURCES += $$PWD/qaudio.cpp \
$$PWD/qaudioengine.cpp \
$$PWD/qaudiodevicefactory.cpp
+contains(QT_CONFIG, audio-backend) {
+
mac {
HEADERS += $$PWD/qaudioinput_mac_p.h \
$$PWD/qaudiooutput_mac_p.h \
@@ -51,3 +53,6 @@ mac {
}
}
}
+} else {
+ DEFINES += QT_NO_AUDIO_BACKEND
+}
diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp
index 89e4394..bc1656d 100644
--- a/src/multimedia/audio/qaudiodevicefactory.cpp
+++ b/src/multimedia/audio/qaudiodevicefactory.cpp
@@ -45,6 +45,7 @@
#include <private/qfactoryloader_p.h>
#include "qaudiodevicefactory_p.h"
+#ifndef QT_NO_AUDIO_BACKEND
#if defined(Q_OS_WIN)
#include "qaudiodeviceinfo_win32_p.h"
#include "qaudiooutput_win32_p.h"
@@ -58,6 +59,7 @@
#include "qaudiooutput_alsa_p.h"
#include "qaudioinput_alsa_p.h"
#endif
+#endif
QT_BEGIN_NAMESPACE
@@ -125,10 +127,12 @@ public:
QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
{
QList<QAudioDeviceInfo> devices;
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
foreach (const QByteArray &handle, QAudioDeviceInfoInternal::availableDevices(mode))
devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode);
#endif
+#endif
QFactoryLoader* l = loader();
foreach (QString const& key, l->keys()) {
@@ -153,9 +157,11 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
if (list.size() > 0)
return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioInput);
}
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultInputDevice(), QAudio::AudioInput);
#endif
+#endif
return QAudioDeviceInfo();
}
@@ -168,9 +174,11 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice()
if (list.size() > 0)
return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioOutput);
}
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultOutputDevice(), QAudio::AudioOutput);
#endif
+#endif
return QAudioDeviceInfo();
}
@@ -178,10 +186,12 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re
{
QAbstractAudioDeviceInfo *rc = 0;
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
if (realm == QLatin1String("builtin"))
return new QAudioDeviceInfoInternal(handle, mode);
#endif
+#endif
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(realm));
@@ -205,10 +215,12 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con
{
if (deviceInfo.isNull())
return new QNullInputDevice();
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
if (deviceInfo.realm() == QLatin1String("builtin"))
return new QAudioInputPrivate(deviceInfo.handle(), format);
#endif
+#endif
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
@@ -222,10 +234,12 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c
{
if (deviceInfo.isNull())
return new QNullOutputDevice();
+#ifndef QT_NO_AUDIO_BACKEND
#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
if (deviceInfo.realm() == QLatin1String("builtin"))
return new QAudioOutputPrivate(deviceInfo.handle(), format);
#endif
+#endif
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
index 9645fa8..f58f5be 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
@@ -403,6 +403,7 @@ void QAudioDeviceInfoInternal::updateLists()
QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
{
+ QList<QByteArray> allDevices;
QList<QByteArray> devices;
QByteArray filter;
@@ -430,6 +431,7 @@ QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
if((name != NULL) && (descr != NULL) && ((io == NULL) || (io == filter))) {
QString deviceName = QLatin1String(name);
QString deviceDescription = QLatin1String(descr);
+ allDevices.append(deviceName.toLocal8Bit().constData());
if(deviceDescription.contains(QLatin1String("Default Audio Device")))
devices.append(deviceName.toLocal8Bit().constData());
}
@@ -457,6 +459,9 @@ QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
if (idx > 0)
devices.append("default");
#endif
+ if (devices.size() == 0 && allDevices.size() > 0)
+ return allDevices;
+
return devices;
}
diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp
index 8b368d5..d81df7a 100644
--- a/src/multimedia/audio/qaudioinput.cpp
+++ b/src/multimedia/audio/qaudioinput.cpp
@@ -77,8 +77,12 @@ QT_BEGIN_NAMESPACE
file, you can:
\code
+ QFile outputFile; // class member.
+ QAudioInput* audio; // class member.
+ \endcode
+
+ \code
{
- QFile outputFile;
outputFile.setFileName("/tmp/test.raw");
outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
@@ -91,7 +95,13 @@ QT_BEGIN_NAMESPACE
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
- QAudioInput *audio = new QAudioInput(format, this);
+ if (QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
+ if (!info.isFormatSupported(format)) {
+ qWarning()<<"default format not supported try to use nearest";
+ format = info.nearestFormat(format);
+ }
+
+ audio = new QAudioInput(format, this);
QTimer::singleShot(3000, this, SLOT(stopRecording()));
audio->start(outputFile);
// Records audio for 3000ms
@@ -109,6 +119,7 @@ QT_BEGIN_NAMESPACE
{
audio->stop();
outputFile->close();
+ delete audio;
}
\endcode
diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp
index b7f9ffd..f50a547 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.cpp
+++ b/src/multimedia/audio/qaudioinput_win32_p.cpp
@@ -153,6 +153,14 @@ WAVEHDR* QAudioInputPrivate::allocateBlocks(int size, int count)
void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
{
+ WAVEHDR* blocks = blockArray;
+
+ int count = buffer_size/period_size;
+
+ for(int i = 0; i < count; i++) {
+ waveInUnprepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR));
+ blocks+=sizeof(WAVEHDR);
+ }
HeapFree(GetProcessHeap(), 0, blockArray);
}
@@ -222,11 +230,6 @@ bool QAudioInputPrivate::open()
} else {
period_size = buffer_size/5;
}
-#ifdef Q_OS_WINCE
- // For wince reduce size to 40ms for buffer size and 20ms period
- buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.04;
- period_size = buffer_size/2;
-#endif
timeStamp.restart();
elapsedTimeOffset = 0;
wfx.nSamplesPerSec = settings.frequency();
@@ -317,7 +320,7 @@ void QAudioInputPrivate::close()
deviceState = QAudio::StoppedState;
int count = 0;
- while(!finished && count < 100) {
+ while(!finished && count < 500) {
count++;
Sleep(10);
}
@@ -349,9 +352,10 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
char* p = data;
qint64 l = 0;
qint64 written = 0;
+
while(!done) {
// Read in some audio data
- if(waveBlocks[header].dwBytesRecorded > 0) {
+ if(waveBlocks[header].dwBytesRecorded > 0 && waveBlocks[header].dwFlags & WHDR_DONE) {
if(pullMode) {
l = audioSource->write(waveBlocks[header].lpData,
waveBlocks[header].dwBytesRecorded);
@@ -394,6 +398,9 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
//no data, not ready yet, next time
return 0;
}
+
+ waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
+
EnterCriticalSection(&waveInCriticalSection);
waveFreeBlockCount++;
LeaveCriticalSection(&waveInCriticalSection);
@@ -401,17 +408,22 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
waveBlocks[header].dwFlags = 0L;
result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
if(result != MMSYSERR_NOERROR) {
+ result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result);
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
+ errorState = QAudio::IOError;
+ EnterCriticalSection(&waveInCriticalSection);
+ waveFreeBlockCount--;
+ LeaveCriticalSection(&waveInCriticalSection);
+ return 0;
}
result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR));
if(result != MMSYSERR_NOERROR) {
qWarning("QAudioInput: failed to setup block %d,err=%d",header,result);
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
+ errorState = QAudio::IOError;
+ EnterCriticalSection(&waveInCriticalSection);
+ waveFreeBlockCount--;
+ LeaveCriticalSection(&waveInCriticalSection);
+ return 0;
}
header++;
if(header >= buffer_size/period_size)
diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp
index f8f2fa1..1c7b617 100644
--- a/src/multimedia/audio/qaudiooutput.cpp
+++ b/src/multimedia/audio/qaudiooutput.cpp
@@ -73,7 +73,11 @@ QT_BEGIN_NAMESPACE
simple as:
\code
- QFile inputFile;
+ QFile inputFile; // class member.
+ QAudioOutput* audio; // class member.
+ \endcode
+
+ \code
inputFile.setFileName("/tmp/test.raw");
inputFile.open(QIODevice::ReadOnly);
@@ -86,7 +90,13 @@ QT_BEGIN_NAMESPACE
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
- QAudioOutput *audio = new QAudioOutput(format, this);
+ QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
+ if (!info.isFormatSupported(format)) {
+ qWarning()<<"raw audio format not supported by backend, cannot play audio.";
+ return;
+ }
+
+ audio = new QAudioOutput(format, this);
connect(audio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State)));
audio->start(inputFile);
@@ -104,6 +114,7 @@ QT_BEGIN_NAMESPACE
if(state == QAudio::IdleState) {
audio->stop();
inputFile.close();
+ delete audio;
}
}
\endcode
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp
index 2cfc472..02c8cfe 100644
--- a/src/multimedia/audio/qaudiooutput_win32_p.cpp
+++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp
@@ -147,6 +147,14 @@ WAVEHDR* QAudioOutputPrivate::allocateBlocks(int size, int count)
void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray)
{
+ WAVEHDR* blocks = blockArray;
+
+ int count = buffer_size/period_size;
+
+ for(int i = 0; i < count; i++) {
+ waveOutUnprepareHeader(hWaveOut,&blocks[i], sizeof(WAVEHDR));
+ blocks+=sizeof(WAVEHDR);
+ }
HeapFree(GetProcessHeap(), 0, blockArray);
}
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index 9ab4057..e6ca367 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -171,7 +171,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
\value UnknownProxyError an unknown proxy-related error
was detected
- \value UnknownContentError an unknonwn error related to
+ \value UnknownContentError an unknown error related to
the remote content was detected
\value ProtocolFailure a breakdown in protocol was
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index c20812e..1667c10 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -273,7 +273,7 @@ void QNetworkReplyImplPrivate::handleNotifications()
if (state != Working)
return;
- while (!current.isEmpty()) {
+ while (state == Working && !current.isEmpty()) {
InternalNotifications notification = current.dequeue();
switch (notification) {
case NotifyDownstreamReadyWrite:
@@ -580,7 +580,7 @@ QNetworkReplyImpl::~QNetworkReplyImpl()
void QNetworkReplyImpl::abort()
{
Q_D(QNetworkReplyImpl);
- if (d->state == QNetworkReplyImplPrivate::Aborted)
+ if (d->state == QNetworkReplyImplPrivate::Finished || d->state == QNetworkReplyImplPrivate::Aborted)
return;
// stop both upload and download
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index c91c608..923f2e3 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -49,6 +49,9 @@
#include "QtCore/qdatetime.h"
#include <ctype.h>
+#ifndef QT_NO_DATESTRING
+# include <stdio.h>
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 98a39cd..e77a425 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -60,11 +60,9 @@
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC(QHostInfoAgent, theAgent)
-void QHostInfoAgent::staticCleanup()
-{
- theAgent()->cleanup();
-}
+#ifndef QT_NO_THREAD
+Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager)
+#endif
//#define QHOSTINFO_DEBUG
@@ -143,6 +141,9 @@ static QBasicAtomicInt theIdCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
\snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 4
+ \note There is no guarantee on the order the signals will be emitted
+ if you start multiple requests with lookupHost().
+
\sa abortHostLookup(), addresses(), error(), fromName()
*/
int QHostInfo::lookupHost(const QString &name, QObject *receiver,
@@ -159,38 +160,32 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
qRegisterMetaType<QHostInfo>("QHostInfo");
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- QWindowsSockInit bust; // makes sure WSAStartup was callled
-#endif
-
- QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
- result.data()->autoDelete = false;
- QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
- receiver, member);
- int id = result.data()->lookupId = theIdCounter.fetchAndAddRelaxed(1);
+ int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID
if (name.isEmpty()) {
- QHostInfo info(id);
- info.setError(QHostInfo::HostNotFound);
- info.setErrorString(QObject::tr("No host name given"));
- QMetaObject::invokeMethod(result.data(), "emitResultsReady", Qt::QueuedConnection,
- Q_ARG(QHostInfo, info));
- result.take()->autoDelete = true;
+ QHostInfo hostInfo(id);
+ hostInfo.setError(QHostInfo::HostNotFound);
+ hostInfo.setErrorString(QObject::tr("No host name given"));
+ QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
+ QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
+ receiver, member, Qt::QueuedConnection);
+ result.data()->emitResultsReady(hostInfo);
return id;
}
- QHostInfoAgent *agent = theAgent();
- agent->addHostName(name, result.take());
-
-#if !defined QT_NO_THREAD
- if (!agent->isRunning())
- agent->start();
+#ifdef QT_NO_THREAD
+ QHostInfo hostInfo = QHostInfoAgent::fromName(name);
+ hostInfo.setLookupId(id);
+ QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
+ QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
+ receiver, member, Qt::QueuedConnection);
+ result.data()->emitResultsReady(hostInfo);
#else
-// if (!agent->isRunning())
- agent->run();
-// else
-// agent->wakeOne();
+ QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
+ QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
+ theHostInfoLookupManager()->scheduleLookup(runnable);
#endif
+
return id;
}
@@ -201,8 +196,12 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
*/
void QHostInfo::abortHostLookup(int id)
{
- QHostInfoAgent *agent = theAgent();
- agent->abortLookup(id);
+#ifndef QT_NO_THREAD
+ theHostInfoLookupManager()->abortLookup(id);
+#else
+ // we cannot abort if it was non threaded.. the result signal has already been posted
+ Q_UNUSED(id);
+#endif
}
/*!
@@ -228,70 +227,6 @@ QHostInfo QHostInfo::fromName(const QString &name)
}
/*!
- \internal
- Pops a query off the queries list, performs a blocking call to
- QHostInfoAgent::lookupHost(), and emits the resultsReady()
- signal. This process repeats until the queries list is empty.
-*/
-void QHostInfoAgent::run()
-{
-#ifndef QT_NO_THREAD
- // Dont' allow thread termination during event delivery, but allow it
- // during the actual blocking host lookup stage.
- setTerminationEnabled(false);
- forever
-#endif
- {
- QHostInfoQuery *query;
- {
-#ifndef QT_NO_THREAD
- // the queries list is shared between threads. lock all
- // access to it.
- QMutexLocker locker(&mutex);
- if (!quit && queries.isEmpty())
- cond.wait(&mutex);
- if (quit) {
- // Reset the quit variable in case QCoreApplication is
- // destroyed and recreated.
- quit = false;
- break;
- }
- if (queries.isEmpty())
- continue;
-#else
- if (queries.isEmpty())
- return;
-#endif
- query = queries.takeFirst();
- pendingQueryId = query->object->lookupId;
- }
-
-#if defined(QHOSTINFO_DEBUG)
- qDebug("QHostInfoAgent::run(%p): looking up \"%s\"", this,
- query->hostName.toLatin1().constData());
-#endif
-
-#ifndef QT_NO_THREAD
- // Start query - allow termination at this point, but not outside. We
- // don't want to all termination during event delivery, but we don't
- // want the lookup to prevent the app from quitting (the agent
- // destructor terminates the thread).
- setTerminationEnabled(true);
-#endif
- QHostInfo info = fromName(query->hostName);
-#ifndef QT_NO_THREAD
- setTerminationEnabled(false);
-#endif
-
- int id = query->object->lookupId;
- info.setLookupId(id);
- if (pendingQueryId == id)
- query->object->emitResultsReady(info);
- delete query;
- }
-}
-
-/*!
\enum QHostInfo::HostInfoError
This enum describes the various errors that can occur when trying
@@ -467,4 +402,174 @@ void QHostInfo::setErrorString(const QString &str)
\sa hostName()
*/
+#ifndef QT_NO_THREAD
+QHostInfoRunnable::QHostInfoRunnable(QString hn, int i) : toBeLookedUp(hn), id(i)
+{
+ setAutoDelete(true);
+}
+
+// the QHostInfoLookupManager will at some point call this via a QThreadPool
+void QHostInfoRunnable::run()
+{
+ QHostInfoLookupManager *manager = theHostInfoLookupManager();
+ // check aborted
+ if (manager->wasAborted(id)) {
+ manager->lookupFinished(this);
+ return;
+ }
+
+ // check cache
+ // FIXME
+
+ // if not in cache: OS lookup
+ QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
+
+ // save to cache
+ // FIXME
+
+ // check aborted again
+ if (manager->wasAborted(id)) {
+ manager->lookupFinished(this);
+ return;
+ }
+
+ // signal emission
+ hostInfo.setLookupId(id);
+ resultEmitter.emitResultsReady(hostInfo);
+
+ manager->lookupFinished(this);
+
+ // thread goes back to QThreadPool
+}
+
+QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), wasDeleted(false)
+{
+ moveToThread(QCoreApplicationPrivate::mainThread());
+ threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel
+}
+
+QHostInfoLookupManager::~QHostInfoLookupManager()
+{
+ wasDeleted = true;
+}
+
+void QHostInfoLookupManager::work()
+{
+ if (wasDeleted)
+ return;
+
+ // goals of this function:
+ // - launch new lookups via the thread pool
+ // - make sure only one lookup per host/IP is in progress
+
+ QMutexLocker locker(&mutex);
+
+ if (!finishedLookups.isEmpty()) {
+ // remove ID from aborted if it is in there
+ for (int i = 0; i < finishedLookups.length(); i++) {
+ abortedLookups.removeAll(finishedLookups.at(i)->id);
+ }
+
+ finishedLookups.clear();
+ }
+
+ if (!postponedLookups.isEmpty()) {
+ // try to start the postponed ones
+
+ QMutableListIterator<QHostInfoRunnable*> iterator(postponedLookups);
+ while (iterator.hasNext()) {
+ QHostInfoRunnable* postponed = iterator.next();
+
+ // check if none of the postponed hostnames is currently running
+ bool alreadyRunning = false;
+ for (int i = 0; i < currentLookups.length(); i++) {
+ if (currentLookups.at(i)->toBeLookedUp == postponed->toBeLookedUp) {
+ alreadyRunning = true;
+ break;
+ }
+ }
+ if (!alreadyRunning) {
+ iterator.remove();
+ scheduledLookups.prepend(postponed); // prepend! we want to finish it ASAP
+ }
+ }
+ }
+
+ if (!scheduledLookups.isEmpty()) {
+ // try to start the new ones
+ QMutableListIterator<QHostInfoRunnable*> iterator(scheduledLookups);
+ while (iterator.hasNext()) {
+ QHostInfoRunnable *scheduled = iterator.next();
+
+ // check if a lookup for this host is already running, then postpone
+ for (int i = 0; i < currentLookups.size(); i++) {
+ if (currentLookups.at(i)->toBeLookedUp == scheduled->toBeLookedUp) {
+ iterator.remove();
+ postponedLookups.append(scheduled);
+ scheduled = 0;
+ break;
+ }
+ }
+
+ if (scheduled && threadPool.tryStart(scheduled)) {
+ // runnable now running in new thread, track this in currentLookups
+ iterator.remove();
+ currentLookups.append(scheduled);
+ } else if (scheduled) {
+ // wanted to start, but could not because thread pool is busy
+ break;
+ } else {
+ // was postponed, continue iterating
+ continue;
+ }
+ };
+ }
+}
+
+// called by QHostInfo
+void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r)
+{
+ if (wasDeleted)
+ return;
+
+ QMutexLocker locker(&this->mutex);
+ scheduledLookups.enqueue(r);
+ work();
+}
+
+// called by QHostInfo
+void QHostInfoLookupManager::abortLookup(int id)
+{
+ if (wasDeleted)
+ return;
+
+ QMutexLocker locker(&this->mutex);
+ if (!abortedLookups.contains(id))
+ abortedLookups.append(id);
+}
+
+// called from QHostInfoRunnable
+bool QHostInfoLookupManager::wasAborted(int id)
+{
+ if (wasDeleted)
+ return true;
+
+ QMutexLocker locker(&this->mutex);
+ return abortedLookups.contains(id);
+}
+
+// called from QHostInfoRunnable
+void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r)
+{
+ if (wasDeleted)
+ return;
+
+ QMutexLocker locker(&this->mutex);
+ currentLookups.removeOne(r);
+ finishedLookups.append(r);
+ work();
+}
+
+#endif // QT_NO_THREAD
+
QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h
index afd3570..643bb73 100644
--- a/src/network/kernel/qhostinfo_p.h
+++ b/src/network/kernel/qhostinfo_p.h
@@ -61,17 +61,17 @@
#include "QtCore/qobject.h"
#include "QtCore/qpointer.h"
-#if !defined QT_NO_THREAD
+#ifndef QT_NO_THREAD
#include "QtCore/qthread.h"
-# define QHostInfoAgentBase QThread
-#else
-# define QHostInfoAgentBase QObject
+#include "QtCore/qthreadpool.h"
+#include "QtCore/qmutex.h"
+#include "QtCore/qrunnable.h"
+#include "QtCore/qlist.h"
+#include "QtCore/qqueue.h"
#endif
QT_BEGIN_NAMESPACE
-static const int QHOSTINFO_THREAD_WAIT = 250; // ms
-
class QHostInfoResult : public QObject
{
Q_OBJECT
@@ -79,102 +79,18 @@ public Q_SLOTS:
inline void emitResultsReady(const QHostInfo &info)
{
emit resultsReady(info);
- if (autoDelete)
- delete this;
}
Q_SIGNALS:
- void resultsReady(const QHostInfo &info);
-
-public:
- int lookupId;
- bool autoDelete;
+ void resultsReady(const QHostInfo info);
};
-struct QHostInfoQuery
-{
- inline QHostInfoQuery() : object(0) {}
- inline ~QHostInfoQuery() { delete object; }
- inline QHostInfoQuery(const QString &name, QHostInfoResult *result)
- : hostName(name), object(result) {}
-
- QString hostName;
- QHostInfoResult *object;
-};
-
-class QHostInfoAgent : public QHostInfoAgentBase
+// needs to be QObject because fromName calls tr()
+class QHostInfoAgent : public QObject
{
Q_OBJECT
public:
- inline QHostInfoAgent()
- {
- // There is a chance that there will be two instances of
- // QHostInfoAgent if two threads try to get Q_GLOBAL_STATIC
- // object at the same time. The second object will be deleted
- // immediately before anyone uses it, but we need to be
- // careful about what we do in the constructor.
- static QBasicAtomicInt done = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (done.testAndSetRelaxed(0, 1))
- qAddPostRoutine(staticCleanup);
- moveToThread(QCoreApplicationPrivate::mainThread());
- quit = false;
- pendingQueryId = -1;
- }
- inline ~QHostInfoAgent()
- { cleanup(); }
-
- void run();
static QHostInfo fromName(const QString &hostName);
-
- inline void addHostName(const QString &name, QHostInfoResult *result)
- {
- QMutexLocker locker(&mutex);
- queries << new QHostInfoQuery(name, result);
- cond.wakeOne();
- }
-
- inline void abortLookup(int id)
- {
- QMutexLocker locker(&mutex);
- for (int i = 0; i < queries.size(); ++i) {
- QHostInfoResult *result = queries.at(i)->object;
- if (result->lookupId == id) {
- result->disconnect();
- delete queries.takeAt(i);
- return;
- }
- }
- if (pendingQueryId == id)
- pendingQueryId = -1;
- }
-
- static void staticCleanup();
-
-public Q_SLOTS:
- inline void cleanup()
- {
- {
- QMutexLocker locker(&mutex);
- qDeleteAll(queries);
- queries.clear();
- quit = true;
- cond.wakeOne();
- }
-#ifndef QT_NO_THREAD
- if (!wait(QHOSTINFO_THREAD_WAIT)) {
- terminate();
- // Don't wait forever; see QTBUG-5296.
- wait(QHOSTINFO_THREAD_WAIT);
- }
-#endif
- }
-
-private:
- QList<QHostInfoQuery *> queries;
- QMutex mutex;
- QWaitCondition cond;
- volatile bool quit;
- int pendingQueryId;
};
class QHostInfoPrivate
@@ -194,6 +110,52 @@ public:
int lookupId;
};
+#ifndef QT_NO_THREAD
+// the following classes are used for the (normal) case: We use multiple threads to lookup DNS
+
+class QHostInfoRunnable : public QRunnable
+{
+public:
+ QHostInfoRunnable (QString hn, int i);
+ void run();
+
+ QString toBeLookedUp;
+ int id;
+ QHostInfoResult resultEmitter;
+};
+
+class QHostInfoLookupManager : public QObject
+{
+ Q_OBJECT
+public:
+ QHostInfoLookupManager();
+ ~QHostInfoLookupManager();
+
+ void work();
+
+ // called from QHostInfo
+ void scheduleLookup(QHostInfoRunnable *r);
+ void abortLookup(int id);
+
+ // called from QHostInfoRunnable
+ void lookupFinished(QHostInfoRunnable *r);
+ bool wasAborted(int id);
+
+protected:
+ QList<QHostInfoRunnable*> currentLookups; // in progress
+ QList<QHostInfoRunnable*> postponedLookups; // postponed because in progress for same host
+ QQueue<QHostInfoRunnable*> scheduledLookups; // not yet started
+ QList<QHostInfoRunnable*> finishedLookups; // recently finished
+ QList<int> abortedLookups; // ids of aborted lookups
+
+ QThreadPool threadPool;
+
+ QMutex mutex;
+
+ bool wasDeleted;
+};
+#endif
+
QT_END_NAMESPACE
#endif // QHOSTINFO_P_H
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index 720aaa5..727a8b0 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -105,11 +105,7 @@ static void resolveLibrary()
#include <qmutex.h>
QMutex qPrivCEMutex;
#endif
-/*
- Performs a blocking call to gethostbyname or getaddrinfo, stores
- the results in a QHostInfo structure and emits the
- resultsReady() signal.
-*/
+
QHostInfo QHostInfoAgent::fromName(const QString &hostName)
{
#if defined(Q_OS_WINCE)
diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
index e319389..e0033be 100644
--- a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
+++ b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
@@ -68,7 +68,7 @@ class Q_OPENGL_EXPORT QGLCustomShaderStage
public:
QGLCustomShaderStage();
virtual ~QGLCustomShaderStage();
- virtual void setUniforms(QGLShaderProgram*) = 0;
+ virtual void setUniforms(QGLShaderProgram*) {}
void setUniformsDirty();
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 8a8f483..d28d5f3 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -170,13 +170,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
source.append(qShaderSnippets[MainVertexShader]);
source.append(qShaderSnippets[PositionOnlyVertexShader]);
vertexShader = new QGLShader(QGLShader::Vertex, context, this);
- vertexShader->compileSourceCode(source);
+ if (!vertexShader->compileSourceCode(source))
+ qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
source.clear();
source.append(qShaderSnippets[MainFragmentShader]);
source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]);
fragShader = new QGLShader(QGLShader::Fragment, context, this);
- fragShader->compileSourceCode(source);
+ if (!fragShader->compileSourceCode(source))
+ qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
simpleShaderProg = new QGLShaderProgram(context, this);
simpleShaderProg->addShader(vertexShader);
@@ -193,13 +195,15 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
source.append(qShaderSnippets[MainWithTexCoordsVertexShader]);
source.append(qShaderSnippets[UntransformedPositionVertexShader]);
vertexShader = new QGLShader(QGLShader::Vertex, context, this);
- vertexShader->compileSourceCode(source);
+ if (!vertexShader->compileSourceCode(source))
+ qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
source.clear();
source.append(qShaderSnippets[MainFragmentShader]);
source.append(qShaderSnippets[ImageSrcFragmentShader]);
fragShader = new QGLShader(QGLShader::Fragment, context, this);
- fragShader->compileSourceCode(source);
+ if (!fragShader->compileSourceCode(source))
+ qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
blitShaderProg = new QGLShaderProgram(context, this);
blitShaderProg->addShader(vertexShader);
@@ -234,84 +238,95 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
}
}
- QByteArray source;
- source.append(qShaderSnippets[prog.mainFragShader]);
- source.append(qShaderSnippets[prog.srcPixelFragShader]);
- if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
- source.append(prog.customStageSource);
- if (prog.compositionFragShader)
- source.append(qShaderSnippets[prog.compositionFragShader]);
- if (prog.maskFragShader)
- source.append(qShaderSnippets[prog.maskFragShader]);
- QGLShader* fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this);
- fragShader->compileSourceCode(source);
-
- source.clear();
- source.append(qShaderSnippets[prog.mainVertexShader]);
- source.append(qShaderSnippets[prog.positionVertexShader]);
- QGLShader* vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this);
- vertexShader->compileSourceCode(source);
+ QGLShader *vertexShader = 0;
+ QGLShader *fragShader = 0;
+ QGLEngineShaderProg *newProg = 0;
+ bool success = false;
+
+ do {
+ QByteArray source;
+ source.append(qShaderSnippets[prog.mainFragShader]);
+ source.append(qShaderSnippets[prog.srcPixelFragShader]);
+ if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
+ source.append(prog.customStageSource);
+ if (prog.compositionFragShader)
+ source.append(qShaderSnippets[prog.compositionFragShader]);
+ if (prog.maskFragShader)
+ source.append(qShaderSnippets[prog.maskFragShader]);
+ fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this);
+ QByteArray description;
+#if defined(QT_DEBUG)
+ // Name the shader for easier debugging
+ description.append("Fragment shader: main=");
+ description.append(snippetNameStr(prog.mainFragShader));
+ description.append(", srcPixel=");
+ description.append(snippetNameStr(prog.srcPixelFragShader));
+ if (prog.compositionFragShader) {
+ description.append(", composition=");
+ description.append(snippetNameStr(prog.compositionFragShader));
+ }
+ if (prog.maskFragShader) {
+ description.append(", mask=");
+ description.append(snippetNameStr(prog.maskFragShader));
+ }
+ fragShader->setObjectName(QString::fromLatin1(description));
+#endif
+ if (!fragShader->compileSourceCode(source)) {
+ qWarning() << "Warning:" << description << "failed to compile!";
+ break;
+ }
+ source.clear();
+ source.append(qShaderSnippets[prog.mainVertexShader]);
+ source.append(qShaderSnippets[prog.positionVertexShader]);
+ vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this);
#if defined(QT_DEBUG)
- // Name the shaders for easier debugging
- QByteArray description;
- description.append("Fragment shader: main=");
- description.append(snippetNameStr(prog.mainFragShader));
- description.append(", srcPixel=");
- description.append(snippetNameStr(prog.srcPixelFragShader));
- if (prog.compositionFragShader) {
- description.append(", composition=");
- description.append(snippetNameStr(prog.compositionFragShader));
- }
- if (prog.maskFragShader) {
- description.append(", mask=");
- description.append(snippetNameStr(prog.maskFragShader));
- }
- fragShader->setObjectName(QString::fromLatin1(description));
-
- description.clear();
- description.append("Vertex shader: main=");
- description.append(snippetNameStr(prog.mainVertexShader));
- description.append(", position=");
- description.append(snippetNameStr(prog.positionVertexShader));
- vertexShader->setObjectName(QString::fromLatin1(description));
+ // Name the shader for easier debugging
+ description.clear();
+ description.append("Vertex shader: main=");
+ description.append(snippetNameStr(prog.mainVertexShader));
+ description.append(", position=");
+ description.append(snippetNameStr(prog.positionVertexShader));
+ vertexShader->setObjectName(QString::fromLatin1(description));
#endif
+ if (!vertexShader->compileSourceCode(source)) {
+ qWarning() << "Warning:" << description << "failed to compile!";
+ break;
+ }
- QGLEngineShaderProg* newProg = new QGLEngineShaderProg(prog);
-
- // If the shader program's not found in the cache, create it now.
- newProg->program = new QGLShaderProgram(ctxGuard.context(), this);
- newProg->program->addShader(vertexShader);
- newProg->program->addShader(fragShader);
-
- // We have to bind the vertex attribute names before the program is linked:
- newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
- if (newProg->useTextureCoords)
- newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
- if (newProg->useOpacityAttribute)
- newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
-
- newProg->program->link();
- if (!newProg->program->isLinked()) {
- QLatin1String none("none");
- QLatin1String br("\n");
- QString error;
- error = QLatin1String("Shader program failed to link,")
+ newProg = new QGLEngineShaderProg(prog);
+
+ // If the shader program's not found in the cache, create it now.
+ newProg->program = new QGLShaderProgram(ctxGuard.context(), this);
+ newProg->program->addShader(vertexShader);
+ newProg->program->addShader(fragShader);
+
+ // We have to bind the vertex attribute names before the program is linked:
+ newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ if (newProg->useTextureCoords)
+ newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+ if (newProg->useOpacityAttribute)
+ newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
+
+ newProg->program->link();
+ if (!newProg->program->isLinked()) {
+ QLatin1String none("none");
+ QLatin1String br("\n");
+ QString error;
+ error = QLatin1String("Shader program failed to link,")
#if defined(QT_DEBUG)
- + br
- + QLatin1String(" Shaders Used:") + br
- + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br
- + QLatin1String(vertexShader->sourceCode()) + br
- + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br
- + QLatin1String(fragShader->sourceCode()) + br
+ + br
+ + QLatin1String(" Shaders Used:") + br
+ + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br
+ + QLatin1String(vertexShader->sourceCode()) + br
+ + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br
+ + QLatin1String(fragShader->sourceCode()) + br
#endif
- + QLatin1String(" Error Log:\n")
- + QLatin1String(" ") + newProg->program->log();
- qWarning() << error;
- delete newProg; // Deletes the QGLShaderProgram in it's destructor
- newProg = 0;
- }
- else {
+ + QLatin1String(" Error Log:\n")
+ + QLatin1String(" ") + newProg->program->log();
+ qWarning() << error;
+ break;
+ }
if (cachedPrograms.count() > 30) {
// The cache is full, so delete the last 5 programs in the list.
// These programs will be least used, as a program us bumped to
@@ -323,6 +338,22 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
}
cachedPrograms.insert(0, newProg);
+
+ success = true;
+ } while (false);
+
+ // Clean up everything if we weren't successful
+ if (!success) {
+ if (newProg) {
+ delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders
+ newProg = 0;
+ }
+ else {
+ if (vertexShader)
+ delete vertexShader;
+ if (fragShader)
+ delete fragShader;
+ }
}
return newProg;
@@ -362,8 +393,11 @@ QGLEngineShaderManager::~QGLEngineShaderManager()
removeCustomStage();
}
-uint QGLEngineShaderManager::getUniformLocation(Uniform id)
+GLuint QGLEngineShaderManager::getUniformLocation(Uniform id)
{
+ if (!currentShaderProg)
+ return 0;
+
QVector<uint> &uniformLocations = currentShaderProg->uniformLocations;
if (uniformLocations.isEmpty())
uniformLocations.fill(GLuint(-1), NumUniforms);
@@ -394,9 +428,9 @@ uint QGLEngineShaderManager::getUniformLocation(Uniform id)
}
-void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform &transform)
+void QGLEngineShaderManager::optimiseForBrushTransform(QTransform::TransformationType transformType)
{
- Q_UNUSED(transform); // Currently ignored
+ Q_UNUSED(transformType); // Currently ignored
}
void QGLEngineShaderManager::setDirty()
@@ -406,6 +440,7 @@ void QGLEngineShaderManager::setDirty()
void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
{
+ Q_ASSERT(style != Qt::NoBrush);
if (srcPixelType == PixelSrcType(style))
return;
@@ -467,7 +502,10 @@ void QGLEngineShaderManager::removeCustomStage()
QGLShaderProgram* QGLEngineShaderManager::currentProgram()
{
- return currentShaderProg->program;
+ if (currentShaderProg)
+ return currentShaderProg->program;
+ else
+ return simpleProgram();
}
QGLShaderProgram* QGLEngineShaderManager::simpleProgram()
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 50c1432..1ec4cdc 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -454,7 +454,7 @@ public:
// There are optimisations we can do, depending on the brush transform:
// 1) May not have to apply perspective-correction
// 2) Can use lower precision for matrix
- void optimiseForBrushTransform(const QTransform &transform);
+ void optimiseForBrushTransform(QTransform::TransformationType transformType);
void setSrcPixelType(Qt::BrushStyle);
void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images
void setOpacityMode(OpacityMode);
@@ -463,7 +463,7 @@ public:
void setCustomStage(QGLCustomShaderStage* stage);
void removeCustomStage();
- uint getUniformLocation(Uniform id);
+ GLuint getUniformLocation(Uniform id);
void setDirty(); // someone has manually changed the current shader program
bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 2407979..46de124 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -99,12 +99,15 @@ static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\
opacity = opacityArray; \
}";
+// NOTE: We let GL do the perspective correction so texture lookups in the fragment
+// shader are also perspective corrected.
static const char* const qglslPositionOnlyVertexShader = "\
- attribute highp vec4 vertexCoordsArray;\
- uniform highp mat4 pmvMatrix;\
+ attribute highp vec2 vertexCoordsArray;\
+ uniform highp mat3 pmvMatrix;\
void setPosition(void)\
{\
- gl_Position = pmvMatrix * vertexCoordsArray;\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \
}";
static const char* const qglslUntransformedPositionVertexShader = "\
@@ -116,20 +119,19 @@ static const char* const qglslUntransformedPositionVertexShader = "\
// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
static const char* const qglslPositionWithPatternBrushVertexShader = "\
- attribute highp vec4 vertexCoordsArray; \
- uniform highp mat4 pmvMatrix; \
+ attribute highp vec2 vertexCoordsArray; \
+ uniform highp mat3 pmvMatrix; \
uniform mediump vec2 halfViewportSize; \
uniform highp vec2 invertedTextureSize; \
uniform highp mat3 brushTransform; \
varying highp vec2 patternTexCoords; \
void setPosition(void) { \
- gl_Position = pmvMatrix * vertexCoordsArray;\
- gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
- mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \
- gl_Position.w = invertedHTexCoordsZ; \
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \
}";
@@ -147,20 +149,19 @@ static const char* const qglslPatternBrushSrcFragmentShader = "\
// Linear Gradient Brush
static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\
- attribute highp vec4 vertexCoordsArray; \
- uniform highp mat4 pmvMatrix; \
+ attribute highp vec2 vertexCoordsArray; \
+ uniform highp mat3 pmvMatrix; \
uniform mediump vec2 halfViewportSize; \
uniform highp vec3 linearData; \
uniform highp mat3 brushTransform; \
varying mediump float index; \
void setPosition() { \
- gl_Position = pmvMatrix * vertexCoordsArray;\
- gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \
- gl_Position.w = invertedHTexCoordsZ; \
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \
}";
@@ -178,20 +179,19 @@ static const char* const qglslLinearGradientBrushSrcFragmentShader = "\
// Conical Gradient Brush
static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\
- attribute highp vec4 vertexCoordsArray;\
- uniform highp mat4 pmvMatrix;\
+ attribute highp vec2 vertexCoordsArray;\
+ uniform highp mat3 pmvMatrix;\
uniform mediump vec2 halfViewportSize; \
uniform highp mat3 brushTransform; \
varying highp vec2 A; \
void setPosition(void)\
{\
- gl_Position = pmvMatrix * vertexCoordsArray;\
- gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \
- gl_Position.w = invertedHTexCoordsZ; \
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
A = hTexCoords.xy * invertedHTexCoordsZ; \
}";
@@ -215,8 +215,8 @@ static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\
// Radial Gradient Brush
static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\
- attribute highp vec4 vertexCoordsArray;\
- uniform highp mat4 pmvMatrix;\
+ attribute highp vec2 vertexCoordsArray;\
+ uniform highp mat3 pmvMatrix;\
uniform mediump vec2 halfViewportSize; \
uniform highp mat3 brushTransform; \
uniform highp vec2 fmp; \
@@ -224,13 +224,12 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\
varying highp vec2 A; \
void setPosition(void) \
{\
- gl_Position = pmvMatrix * vertexCoordsArray;\
- gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \
- gl_Position.w = invertedHTexCoordsZ; \
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
A = hTexCoords.xy * invertedHTexCoordsZ; \
b = 2.0 * dot(A, fmp); \
}";
@@ -253,20 +252,19 @@ static const char* const qglslRadialGradientBrushSrcFragmentShader = "\
// Texture Brush
static const char* const qglslPositionWithTextureBrushVertexShader = "\
- attribute highp vec4 vertexCoordsArray; \
- uniform highp mat4 pmvMatrix; \
+ attribute highp vec2 vertexCoordsArray; \
+ uniform highp mat3 pmvMatrix; \
uniform mediump vec2 halfViewportSize; \
uniform highp vec2 invertedTextureSize; \
uniform highp mat3 brushTransform; \
varying highp vec2 textureCoords; \
void setPosition(void) { \
- gl_Position = pmvMatrix * vertexCoordsArray;\
- gl_Position.xy = gl_Position.xy / gl_Position.w; \
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \
mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \
- gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \
- gl_Position.w = invertedHTexCoordsZ; \
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \
textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \
}";
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 3fce384..d3a9547 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -358,10 +358,10 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
- if (id != GLuint(-1) && id == lastTexture)
+ if (id != GLuint(-1) && id == lastTextureUsed)
return;
- lastTexture = id;
+ lastTextureUsed = id;
if (smoothPixmapTransform) {
glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -386,19 +386,28 @@ inline QColor qt_premultiplyColor(QColor c, GLfloat opacity)
}
-void QGL2PaintEngineExPrivate::setBrush(const QBrush* brush)
+void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush)
{
+ if (qbrush_fast_equals(currentBrush, brush))
+ return;
+
+ const Qt::BrushStyle newStyle = qbrush_style(brush);
+ Q_ASSERT(newStyle != Qt::NoBrush);
+
currentBrush = brush;
- brushTextureDirty = true;
- brushUniformsDirty = true;
- if (currentBrush->style() == Qt::TexturePattern
- && qHasPixmapTexture(*brush) && brush->texture().isQBitmap())
+ brushUniformsDirty = true; // All brushes have at least one uniform
+
+ if (newStyle > Qt::SolidPattern)
+ brushTextureDirty = true;
+
+ if (currentBrush.style() == Qt::TexturePattern
+ && qHasPixmapTexture(brush) && brush.texture().isQBitmap())
{
shaderManager->setSrcPixelType(QGLEngineShaderManager::TextureSrcWithPattern);
} else {
- shaderManager->setSrcPixelType(currentBrush->style());
+ shaderManager->setSrcPixelType(newStyle);
}
- shaderManager->optimiseForBrushTransform(currentBrush->transform());
+ shaderManager->optimiseForBrushTransform(currentBrush.transform().type());
}
@@ -420,7 +429,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
{
Q_Q(QGL2PaintEngineEx);
// qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()");
- Qt::BrushStyle style = currentBrush->style();
+ Qt::BrushStyle style = currentBrush.style();
if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) {
// Get the image data for the pattern
@@ -433,7 +442,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
// Gradiant brush: All the gradiants use the same texture
- const QGradient* g = currentBrush->gradient();
+ const QGradient* g = currentBrush.gradient();
// We apply global opacity in the fragment shaders, so we always pass 1.0
// for opacity to the cache.
@@ -450,7 +459,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style == Qt::TexturePattern) {
- const QPixmap& texPixmap = currentBrush->texture();
+ const QPixmap& texPixmap = currentBrush.texture();
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
@@ -464,15 +473,15 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
void QGL2PaintEngineExPrivate::updateBrushUniforms()
{
// qDebug("QGL2PaintEngineExPrivate::updateBrushUniforms()");
- Qt::BrushStyle style = currentBrush->style();
+ Qt::BrushStyle style = currentBrush.style();
if (style == Qt::NoBrush)
return;
- QTransform brushQTransform = currentBrush->transform();
+ QTransform brushQTransform = currentBrush.transform();
if (style == Qt::SolidPattern) {
- QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::FragmentColor), col);
}
else {
@@ -480,7 +489,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
QPointF translationPoint;
if (style <= Qt::DiagCrossPattern) {
- QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col);
@@ -488,7 +497,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize);
}
else if (style == Qt::LinearGradientPattern) {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush->gradient());
+ const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush.gradient());
QPointF realStart = g->start();
QPointF realFinal = g->finalStop();
@@ -508,7 +517,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize);
}
else if (style == Qt::ConicalGradientPattern) {
- const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush->gradient());
+ const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush.gradient());
translationPoint = g->center();
GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0;
@@ -519,7 +528,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize);
}
else if (style == Qt::RadialGradientPattern) {
- const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush->gradient());
+ const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush.gradient());
QPointF realCenter = g->center();
QPointF realFocal = g->focalPoint();
qreal realRadius = g->radius();
@@ -537,10 +546,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize);
}
else if (style == Qt::TexturePattern) {
- const QPixmap& texPixmap = currentBrush->texture();
+ const QPixmap& texPixmap = currentBrush.texture();
- if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) {
- QColor col = qt_premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
+ if (qHasPixmapTexture(currentBrush) && currentBrush.texture().isQBitmap()) {
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col);
}
@@ -561,7 +570,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
QTransform gl_to_qt(1, 0, 0, -1, 0, height);
QTransform inv_matrix;
if (style == Qt::TexturePattern && textureInvertedY == -1)
- inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush->texture().height()) * brushQTransform * matrix).inverted() * translate;
+ inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush.texture().height()) * brushQTransform * matrix).inverted() * translate;
else
inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate;
@@ -577,66 +586,50 @@ void QGL2PaintEngineExPrivate::updateMatrix()
{
// qDebug("QGL2PaintEngineExPrivate::updateMatrix()");
- // We set up the 4x4 transformation matrix on the vertex shaders to
- // be the equivalent of glOrtho(0, w, h, 0, -1, 1) * transform:
+ const QTransform& transform = q->state()->matrix;
+
+ // The projection matrix converts from Qt's coordinate system to GL's coordinate system
+ // * GL's viewport is 2x2, Qt's is width x height
+ // * GL has +y -> -y going from bottom -> top, Qt is the other way round
+ // * GL has [0,0] in the center, Qt has it in the top-left
//
- // | 2/width 0 0 -1 | | m11 m21 0 dx |
- // | 0 -2/height 0 1 | | m12 m22 0 dy |
- // | 0 0 -1 0 | * | 0 0 1 0 |
- // | 0 0 0 1 | | m13 m23 0 m33 |
+ // This results in the Projection matrix below, which is multiplied by the painter's
+ // transformation matrix, as shown below:
//
- // We expand out the multiplication to save the cost of a full 4x4
- // matrix multiplication as most of the components are trivial.
- const QTransform& transform = q->state()->matrix;
+ // Projection Matrix Painter Transform
+ // ------------------------------------------------ ------------------------
+ // | 2.0 / width | 0.0 | -1.0 | | m11 | m21 | dx |
+ // | 0.0 | -2.0 / height | 1.0 | * | m12 | m22 | dy |
+ // | 0.0 | 0.0 | 1.0 | | m13 | m23 | m33 |
+ // ------------------------------------------------ ------------------------
+ //
+ // NOTE: The resultant matrix is also transposed, as GL expects column-major matracies
+
+ const GLfloat wfactor = 2.0f / width;
+ const GLfloat hfactor = -2.0f / height;
- if (mode == TextDrawingMode) {
- // Text drawing mode is only used for non-scaling transforms
- pmvMatrix[0][0] = 2.0 / width;
- pmvMatrix[0][1] = 0.0;
- pmvMatrix[0][2] = 0.0;
- pmvMatrix[0][3] = 0.0;
- pmvMatrix[1][0] = 0.0;
- pmvMatrix[1][1] = -2.0 / height;
- pmvMatrix[1][2] = 0.0;
- pmvMatrix[1][3] = 0.0;
- pmvMatrix[2][0] = 0.0;
- pmvMatrix[2][1] = 0.0;
- pmvMatrix[2][2] = -1.0;
- pmvMatrix[2][3] = 0.0;
- pmvMatrix[3][0] = pmvMatrix[0][0] * qRound(transform.dx()) - 1.0;
- pmvMatrix[3][1] = pmvMatrix[1][1] * qRound(transform.dy()) + 1.0;
- pmvMatrix[3][2] = 0.0;
- pmvMatrix[3][3] = 1.0;
-
- inverseScale = 1;
+ if (addOffset) {
+ pmvMatrix[2][0] = (wfactor * (transform.dx() + 0.49f)) - transform.m33();
+ pmvMatrix[2][1] = (hfactor * (transform.dy() + 0.49f)) + transform.m33();
} else {
- qreal wfactor = 2.0 / width;
- qreal hfactor = -2.0 / height;
-
- pmvMatrix[0][0] = wfactor * transform.m11() - transform.m13();
- pmvMatrix[0][1] = hfactor * transform.m12() + transform.m13();
- pmvMatrix[0][2] = 0.0;
- pmvMatrix[0][3] = transform.m13();
- pmvMatrix[1][0] = wfactor * transform.m21() - transform.m23();
- pmvMatrix[1][1] = hfactor * transform.m22() + transform.m23();
- pmvMatrix[1][2] = 0.0;
- pmvMatrix[1][3] = transform.m23();
- pmvMatrix[2][0] = 0.0;
- pmvMatrix[2][1] = 0.0;
- pmvMatrix[2][2] = -1.0;
- pmvMatrix[2][3] = 0.0;
- pmvMatrix[3][0] = wfactor * transform.dx() - transform.m33();
- pmvMatrix[3][1] = hfactor * transform.dy() + transform.m33();
- pmvMatrix[3][2] = 0.0;
- pmvMatrix[3][3] = transform.m33();
-
- // 1/10000 == 0.0001, so we have good enough res to cover curves
- // that span the entire widget...
- inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())),
- qMax(qAbs(transform.m12()), qAbs(transform.m21())) ),
- qreal(0.0001));
+ pmvMatrix[2][0] = (wfactor * transform.dx()) - transform.m33();
+ pmvMatrix[2][1] = (hfactor * transform.dy()) + transform.m33();
}
+ pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13();
+ pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23();
+ pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13();
+ pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23();
+ pmvMatrix[0][2] = transform.m13();
+ pmvMatrix[1][2] = transform.m23();
+ pmvMatrix[2][2] = transform.m33();
+
+ // 1/10000 == 0.0001, so we have good enough res to cover curves
+ // that span the entire widget...
+ inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())),
+ qMax(qAbs(transform.m12()), qAbs(transform.m21())) ),
+ qreal(0.0001));
+
matrixDirty = false;
// The actual data has been updated so both shader program's uniforms need updating
@@ -716,7 +709,14 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect)
void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern)
{
// Setup for texture drawing
+ currentBrush = noBrush;
shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc);
+
+ if (addOffset) {
+ addOffset = false;
+ matrixDirty = true;
+ }
+
if (prepareForDraw(opaque))
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
@@ -771,7 +771,7 @@ void QGL2PaintEngineEx::beginNativePainting()
Q_UNUSED(ctx);
#endif
- d->lastTexture = GLuint(-1);
+ d->lastTextureUsed = GLuint(-1);
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
d->resetGLState();
@@ -798,12 +798,6 @@ void QGL2PaintEngineEx::endNativePainting()
d->needsSync = true;
}
-const QGLContext *QGL2PaintEngineEx::context()
-{
- Q_D(QGL2PaintEngineEx);
- return d->ctx;
-}
-
void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode)
{
if (newMode == mode)
@@ -814,20 +808,15 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode)
glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
glDisableVertexAttribArray(QT_OPACITY_ATTR);
- lastTexture = GLuint(-1);
+ lastTextureUsed = GLuint(-1);
}
- if (mode == TextDrawingMode)
- matrixDirty = true;
-
if (newMode == TextDrawingMode) {
glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
-
- matrixDirty = true;
}
if (newMode == ImageDrawingMode) {
@@ -867,13 +856,14 @@ struct QGL2PEVectorPathCache
qreal iscale;
};
-void qopengl2paintengine_cleanup_vectorpath(QPaintEngineEx *engine, void *data)
+void QGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data)
{
QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data;
#ifdef QT_OPENGL_CACHE_AS_VBOS
- QGL2PaintEngineExPrivate *d = QGL2PaintEngineExPrivate::getData((QGL2PaintEngineEx *) engine);
- d->unusedVBOSToClean << c->vbo;
+ Q_ASSERT(engine->type() == QPaintEngine::OpenGL2);
+ static_cast<QGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo;
#else
+ Q_UNUSED(engine);
qFree(c->vertices);
#endif
delete c;
@@ -884,6 +874,16 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
{
transferMode(BrushDrawingMode);
+ const QOpenGL2PaintEngineState *s = q->state();
+ const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) &&
+ (qbrush_style(currentBrush) == Qt::SolidPattern) &&
+ !multisamplingAlwaysEnabled;
+
+ if (addOffset != newAddOffset) {
+ addOffset = newAddOffset;
+ matrixDirty = true;
+ }
+
// Might need to call updateMatrix to re-calculate inverseScale
if (matrixDirty)
updateMatrix();
@@ -893,7 +893,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
// Check to see if there's any hints
if (path.shape() == QVectorPath::RectangleHint) {
QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y());
- prepareForDraw(currentBrush->isOpaque());
+ prepareForDraw(currentBrush.isOpaque());
composite(rect);
} else if (path.isConvex()) {
@@ -919,7 +919,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
} else {
cache = new QGL2PEVectorPathCache;
cache->vertexCount = 0;
- data = const_cast<QVectorPath &>(path).addCacheData(q, cache, qopengl2paintengine_cleanup_vectorpath);
+ data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath);
}
// Flatten the path at the current scale factor and fill it into the cache struct.
@@ -930,7 +930,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
int floatSizeInBytes = vertexCount * 2 * sizeof(float);
cache->vertexCount = vertexCount;
cache->primitiveType = GL_TRIANGLE_FAN;
- cache->iscale = inverseScale;
+ cache->iscale = inverseScale;
#ifdef QT_OPENGL_CACHE_AS_VBOS
glGenBuffers(1, &cache->vbo);
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
@@ -941,7 +941,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
#endif
}
- prepareForDraw(currentBrush->isOpaque());
+ prepareForDraw(currentBrush.isOpaque());
glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
#ifdef QT_OPENGL_CACHE_AS_VBOS
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
@@ -960,7 +960,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
path.makeCacheable();
vertexCoordinateArray.clear();
vertexCoordinateArray.addPath(path, inverseScale, false);
- prepareForDraw(currentBrush->isOpaque());
+ prepareForDraw(currentBrush.isOpaque());
drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);
}
@@ -985,7 +985,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
}
- prepareForDraw(currentBrush->isOpaque());
+ prepareForDraw(currentBrush.isOpaque());
if (inRenderText)
prepareDepthRangeForRenderText();
@@ -1182,10 +1182,10 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
: QGLEngineShaderManager::NoOpacity;
if (stateHasOpacity && (mode != ImageDrawingMode)) {
// Using a brush
- bool brushIsPattern = (currentBrush->style() >= Qt::Dense1Pattern) &&
- (currentBrush->style() <= Qt::DiagCrossPattern);
+ bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) &&
+ (currentBrush.style() <= Qt::DiagCrossPattern);
- if ((currentBrush->style() == Qt::SolidPattern) || brushIsPattern)
+ if ((currentBrush.style() == Qt::SolidPattern) || brushIsPattern)
opacityMode = QGLEngineShaderManager::NoOpacity; // Global opacity handled by srcPixel shader
}
}
@@ -1295,31 +1295,14 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)
{
Q_D(QGL2PaintEngineEx);
- Qt::BrushStyle style = qbrush_style(brush);
- if (style == Qt::NoBrush)
+ if (qbrush_style(brush) == Qt::NoBrush)
return;
+
if (!d->inRenderText)
ensureActive();
- QOpenGL2PaintEngineState *s = state();
- bool doOffset = !(s->renderHints & QPainter::Antialiasing) &&
- (style == Qt::SolidPattern) &&
- !d->multisamplingAlwaysEnabled;
-
- if (doOffset) {
- d->temporaryTransform = s->matrix;
- QTransform tx = QTransform::fromTranslate(.49, .49);
- s->matrix = s->matrix * tx;
- d->matrixDirty = true;
- }
-
- d->setBrush(&brush);
+ d->setBrush(brush);
d->fill(path);
-
- if (doOffset) {
- s->matrix = d->temporaryTransform;
- d->matrixDirty = true;
- }
}
extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
@@ -1329,9 +1312,8 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
{
Q_D(QGL2PaintEngineEx);
- Qt::PenStyle penStyle = qpen_style(pen);
const QBrush &penBrush = qpen_brush(pen);
- if (penStyle == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush)
+ if (qpen_style(pen) == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush)
return;
QOpenGL2PaintEngineState *s = state();
@@ -1342,45 +1324,47 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
}
ensureActive();
+ d->setBrush(penBrush);
+ d->stroke(path, pen);
+}
- bool doOffset = !(s->renderHints & QPainter::Antialiasing) && !d->multisamplingAlwaysEnabled;
- if (doOffset) {
- d->temporaryTransform = s->matrix;
- QTransform tx = QTransform::fromTranslate(0.49, .49);
- s->matrix = s->matrix * tx;
- d->matrixDirty = true;
+void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen)
+{
+ const QOpenGL2PaintEngineState *s = q->state();
+ const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) && !multisamplingAlwaysEnabled;
+ if (addOffset != newAddOffset) {
+ addOffset = newAddOffset;
+ matrixDirty = true;
}
- bool opaque = penBrush.isOpaque() && s->opacity > 0.99;
- d->setBrush(&penBrush);
- d->transferMode(BrushDrawingMode);
+ const Qt::PenStyle penStyle = qpen_style(pen);
+ const QBrush &penBrush = qpen_brush(pen);
+ const bool opaque = penBrush.isOpaque() && s->opacity > 0.99;
+
+ transferMode(BrushDrawingMode);
// updateMatrix() is responsible for setting the inverse scale on
// the strokers, so we need to call it here and not wait for
// prepareForDraw() down below.
- d->updateMatrix();
+ updateMatrix();
if (penStyle == Qt::SolidLine) {
- d->stroker.process(path, pen);
+ stroker.process(path, pen);
} else { // Some sort of dash
- d->dasher.process(path, pen);
+ dasher.process(path, pen);
- QVectorPath dashStroke(d->dasher.points(),
- d->dasher.elementCount(),
- d->dasher.elementTypes());
- d->stroker.process(dashStroke, pen);
+ QVectorPath dashStroke(dasher.points(),
+ dasher.elementCount(),
+ dasher.elementTypes());
+ stroker.process(dashStroke, pen);
}
-
- QGLContext *ctx = d->ctx;
- Q_UNUSED(ctx);
-
if (opaque) {
- d->prepareForDraw(opaque);
+ prepareForDraw(opaque);
glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, d->stroker.vertices());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, d->stroker.vertexCount() / 2);
+ glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, stroker.vertices());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2);
// QBrush b(Qt::green);
// d->setBrush(&b);
@@ -1398,30 +1382,25 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
: width;
if (pen.isCosmetic())
- extra = extra * d->inverseScale;
+ extra = extra * inverseScale;
QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra);
- d->fillStencilWithVertexArray(d->stroker.vertices(), d->stroker.vertexCount() / 2,
+ fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2,
0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode);
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
// Pass when any bit is set, replace stencil value with 0
glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
- d->prepareForDraw(false);
+ prepareForDraw(false);
// Stencil the brush onto the dest buffer
- d->composite(bounds);
+ composite(bounds);
glStencilMask(0);
- d->updateClipScissorTest();
- }
-
- if (doOffset) {
- s->matrix = d->temporaryTransform;
- d->matrixDirty = true;
+ updateClipScissorTest();
}
}
@@ -1461,7 +1440,7 @@ void QGL2PaintEngineEx::renderHintsChanged()
#endif
Q_D(QGL2PaintEngineEx);
- d->lastTexture = GLuint(-1);
+ d->lastTextureUsed = GLuint(-1);
d->brushTextureDirty = true;
// qDebug("QGL2PaintEngineEx::renderHintsChanged() not implemented!");
}
@@ -1545,21 +1524,21 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- bool drawCached = true;
+ QTransform::TransformationType txtype = s->matrix.type();
- if (s->matrix.type() > QTransform::TxTranslate)
- drawCached = false;
+ float det = s->matrix.determinant();
+ bool drawCached = txtype < QTransform::TxProject;
- // don't try to cache huge fonts
+ // don't try to cache huge fonts or vastly transformed fonts
const qreal pixelSize = ti.fontEngine->fontDef.pixelSize;
- if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64)
+ if (pixelSize * pixelSize * qAbs(det) >= 64 * 64 || det < 0.25f || det > 4.f)
drawCached = false;
QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0
? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat)
: d->glyphCacheType;
- if (d->inRenderText)
+ if (d->inRenderText || txtype > QTransform::TxTranslate)
glyphType = QFontEngineGlyphCache::Raster_A8;
if (glyphType == QFontEngineGlyphCache::Raster_RGBMask
@@ -1581,7 +1560,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
const QTextItemInt &ti)
{
Q_Q(QGL2PaintEngineEx);
- QOpenGL2PaintEngineState *s = q->state();
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
@@ -1589,10 +1567,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
QGLTextureGlyphCache *cache =
- (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, s->matrix);
+ (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, glyphType, QTransform());
if (!cache || cache->cacheType() != glyphType) {
- cache = new QGLTextureGlyphCache(ctx, glyphType, s->matrix);
+ cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
ti.fontEngine->setGlyphCache(ctx, cache);
}
@@ -1631,8 +1609,13 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
if (textureCoordinateArray.data() != oldTextureCoordinateDataPtr)
glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
+ if (addOffset) {
+ addOffset = false;
+ matrixDirty = true;
+ }
+
QBrush pensBrush = q->state()->pen.brush();
- setBrush(&pensBrush);
+ setBrush(pensBrush);
if (inRenderText)
prepareDepthRangeForRenderText();
@@ -1677,7 +1660,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
q->state()->opacity = 1;
opacityUniformDirty = true;
pensBrush = Qt::white;
- setBrush(&pensBrush);
+ setBrush(pensBrush);
}
compositionModeDirty = false; // I can handle this myself, thank you very much
@@ -1698,7 +1681,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
q->state()->opacity = oldOpacity;
opacityUniformDirty = true;
pensBrush = q->state()->pen.brush();
- setBrush(&pensBrush);
+ setBrush(pensBrush);
}
compositionModeDirty = false;
@@ -1728,20 +1711,31 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly
void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
{
+ Q_D(QGL2PaintEngineEx);
// Use fallback for extended composition modes.
if (state()->composition_mode > QPainter::CompositionMode_Plus) {
QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
return;
}
- Q_D(QGL2PaintEngineEx);
+ ensureActive();
+ d->drawPixmaps(drawingData, dataCount, pixmap, hints);
+}
+
+void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
+{
GLfloat dx = 1.0f / pixmap.size().width();
GLfloat dy = 1.0f / pixmap.size().height();
- d->vertexCoordinateArray.clear();
- d->textureCoordinateArray.clear();
- d->opacityArray.reset();
+ vertexCoordinateArray.clear();
+ textureCoordinateArray.clear();
+ opacityArray.reset();
+
+ if (addOffset) {
+ addOffset = false;
+ matrixDirty = true;
+ }
bool allOpaque = true;
@@ -1758,31 +1752,28 @@ void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int d
QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c);
QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c);
- d->vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
- d->vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y());
- d->vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
- d->vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
- d->vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y());
- d->vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
QGLRect src(drawingData[i].source.left() * dx, drawingData[i].source.top() * dy,
drawingData[i].source.right() * dx, drawingData[i].source.bottom() * dy);
- d->textureCoordinateArray.lineToArray(src.right, src.bottom);
- d->textureCoordinateArray.lineToArray(src.right, src.top);
- d->textureCoordinateArray.lineToArray(src.left, src.top);
- d->textureCoordinateArray.lineToArray(src.left, src.top);
- d->textureCoordinateArray.lineToArray(src.left, src.bottom);
- d->textureCoordinateArray.lineToArray(src.right, src.bottom);
+ textureCoordinateArray.lineToArray(src.right, src.bottom);
+ textureCoordinateArray.lineToArray(src.right, src.top);
+ textureCoordinateArray.lineToArray(src.left, src.top);
+ textureCoordinateArray.lineToArray(src.left, src.top);
+ textureCoordinateArray.lineToArray(src.left, src.bottom);
+ textureCoordinateArray.lineToArray(src.right, src.bottom);
- qreal opacity = drawingData[i].opacity * state()->opacity;
- d->opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;
+ qreal opacity = drawingData[i].opacity * q->state()->opacity;
+ opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;
allOpaque &= (opacity >= 0.99f);
}
- ensureActive();
-
- QGLContext *ctx = d->ctx;
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
QGLContext::InternalBindOption
@@ -1790,27 +1781,28 @@ void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int d
if (texture->options & QGLContext::InvertedYBindOption) {
// Flip texture y-coordinate.
- QGLPoint *data = d->textureCoordinateArray.data();
+ QGLPoint *data = textureCoordinateArray.data();
for (int i = 0; i < 6 * dataCount; ++i)
data[i].y = 1 - data[i].y;
}
- d->transferMode(ImageArrayDrawingMode);
+ transferMode(ImageArrayDrawingMode);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && (!pixmap.hasAlphaChannel() || (hints & QDrawPixmaps::OpaqueHint)) && allOpaque;
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
+ updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
// Setup for texture drawing
- d->shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc);
- if (d->prepareForDraw(isOpaque))
- d->shaderManager->currentProgram()->setUniformValue(d->location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
+ currentBrush = noBrush;
+ shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc);
+ if (prepareForDraw(isOpaque))
+ shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
if (isBitmap) {
- QColor col = qt_premultiplyColor(state()->pen.color(), (GLfloat)state()->opacity);
- d->shaderManager->currentProgram()->setUniformValue(d->location(QGLEngineShaderManager::PatternColor), col);
+ QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);
+ shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col);
}
glDrawArrays(GL_TRIANGLES, 0, 6 * dataCount);
@@ -1842,7 +1834,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->compositionModeDirty = true;
d->opacityUniformDirty = true;
d->needsSync = true;
- d->use_system_clip = !systemClip().isEmpty();
+ d->useSystemClip = !systemClip().isEmpty();
+ d->currentBrush = QBrush();
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
d->stencilClean = true;
@@ -1962,12 +1955,12 @@ void QGL2PaintEngineExPrivate::updateClipScissorTest()
#else
QRect bounds = q->state()->rectangleClip;
if (!q->state()->clipEnabled) {
- if (use_system_clip)
+ if (useSystemClip)
bounds = systemClip.boundingRect();
else
bounds = QRect(0, 0, width, height);
} else {
- if (use_system_clip)
+ if (useSystemClip)
bounds = bounds.intersected(systemClip.boundingRect());
else
bounds = bounds.intersected(QRect(0, 0, width, height));
@@ -2022,6 +2015,11 @@ void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value)
{
transferMode(BrushDrawingMode);
+ if (addOffset) {
+ addOffset = false;
+ matrixDirty = true;
+ }
+
if (matrixDirty)
updateMatrix();
@@ -2121,7 +2119,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
switch (op) {
case Qt::NoClip:
- if (d->use_system_clip) {
+ if (d->useSystemClip) {
state()->clipTestEnabled = true;
state()->currentClip = 1;
} else {
@@ -2193,13 +2191,13 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
q->state()->clipChanged = true;
if (systemClip.isEmpty()) {
- use_system_clip = false;
+ useSystemClip = false;
} else {
if (q->paintDevice()->devType() == QInternal::Widget && currentClipWidget) {
QWidgetPrivate *widgetPrivate = qt_widget_private(currentClipWidget->window());
- use_system_clip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
+ useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
} else {
- use_system_clip = true;
+ useSystemClip = true;
}
}
@@ -2209,19 +2207,19 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
q->state()->currentClip = 1;
maxClip = 1;
- q->state()->rectangleClip = use_system_clip ? systemClip.boundingRect() : QRect(0, 0, width, height);
+ q->state()->rectangleClip = useSystemClip ? systemClip.boundingRect() : QRect(0, 0, width, height);
updateClipScissorTest();
if (systemClip.rectCount() == 1) {
if (systemClip.boundingRect() == QRect(0, 0, width, height))
- use_system_clip = false;
+ useSystemClip = false;
#ifndef QT_GL_NO_SCISSOR_TEST
// scissoring takes care of the system clip
return;
#endif
}
- if (use_system_clip) {
+ if (useSystemClip) {
clearClip(0);
QPainterPath path;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 0084476..c94c4f4 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -105,13 +105,8 @@ public:
~QGL2PaintEngineEx();
bool begin(QPaintDevice *device);
- bool end();
-
void ensureActive();
-
- virtual void fill(const QVectorPath &path, const QBrush &brush);
- virtual void stroke(const QVectorPath &path, const QPen &pen);
- virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
+ bool end();
virtual void clipEnabledChanged();
virtual void penChanged();
@@ -122,20 +117,21 @@ public:
virtual void renderHintsChanged();
virtual void transformChanged();
-
+ virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
Qt::ImageConversionFlags flags = Qt::AutoColor);
- virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
-
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ virtual void fill(const QVectorPath &path, const QBrush &brush);
+ virtual void stroke(const QVectorPath &path, const QPen &pen);
+ virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
- virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
Type type() const { return OpenGL2; }
- void setState(QPainterState *s);
- QPainterState *createState(QPainterState *orig) const;
+ virtual void setState(QPainterState *s);
+ virtual QPainterState *createState(QPainterState *orig) const;
inline QOpenGL2PaintEngineState *state() {
return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
}
@@ -146,8 +142,6 @@ public:
void beginNativePainting();
void endNativePainting();
- const QGLContext* context();
-
QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
void setRenderTextActive(bool);
@@ -169,11 +163,12 @@ public:
QGL2PaintEngineExPrivate(QGL2PaintEngineEx *q_ptr) :
q(q_ptr),
+ shaderManager(0),
width(0), height(0),
ctx(0),
- currentBrush(0),
+ useSystemClip(true),
+ addOffset(false),
inverseScale(1),
- shaderManager(0),
inRenderText(false)
{ }
@@ -185,45 +180,62 @@ public:
void updateCompositionMode();
void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1);
- void setBrush(const QBrush* brush);
-
- void transferMode(EngineMode newMode);
void resetGLState();
- // fill, drawOutline, drawTexture & drawCachedGlyphs are the rendering entry points:
+ // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
+ // however writeClip can also be thought of as en entry point as it does similar things.
void fill(const QVectorPath &path);
+ void stroke(const QVectorPath &path, const QPen &pen);
void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
+ void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti);
+ // draws whatever is in the vertex array:
void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive);
void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) {
drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive);
}
- // ^ draws whatever is in the vertex array
+ // Composites the bounding rect onto dest buffer:
void composite(const QGLRect& boundingRect);
- // ^ Composites the bounding rect onto dest buffer
+ // Calls drawVertexArrays to render into stencil buffer:
void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode);
void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) {
fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(),
vertexArray.boundingRect(),
useWindingFill ? WindingFillMode : OddEvenFillMode);
}
- // ^ Calls drawVertexArrays to render into stencil buffer
-
- bool prepareForDraw(bool srcPixelsAreOpaque);
- // ^ returns whether the current program changed or not
+ void setBrush(const QBrush& brush);
+ void transferMode(EngineMode newMode);
+ bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed
inline void useSimpleShader();
+ inline GLuint location(const QGLEngineShaderManager::Uniform uniform) {
+ return shaderManager->getUniformLocation(uniform);
+ }
+
void prepareDepthRangeForRenderText();
void restoreDepthRangeForRenderText();
+ void clearClip(uint value);
+ void writeClip(const QVectorPath &path, uint value);
+ void resetClipIfNeeded();
+
+ void updateClipScissorTest();
+ void setScissor(const QRect &rect);
+ void regenerateClip();
+ void systemStateChanged();
+
+
static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); }
+ static void cleanupVectorPath(QPaintEngineEx *engine, void *data);
+
QGL2PaintEngineEx* q;
+ QGLEngineShaderManager* shaderManager;
QGLPaintDevice* device;
int width, height;
QGLContext *ctx;
@@ -240,41 +252,25 @@ public:
bool opacityUniformDirty;
bool stencilClean; // Has the stencil not been used for clipping so far?
+ bool useSystemClip;
QRegion dirtyStencilRegion;
QRect currentScissorBounds;
uint maxClip;
- const QBrush* currentBrush; // May not be the state's brush!
-
- GLfloat inverseScale;
+ QBrush currentBrush; // May not be the state's brush!
+ const QBrush noBrush;
QGL2PEXVertexArray vertexCoordinateArray;
QGL2PEXVertexArray textureCoordinateArray;
QDataBuffer<GLfloat> opacityArray;
-
GLfloat staticVertexCoordinateArray[8];
GLfloat staticTextureCoordinateArray[8];
- GLfloat pmvMatrix[4][4];
-
- QGLEngineShaderManager* shaderManager;
-
- void clearClip(uint value);
- void writeClip(const QVectorPath &path, uint value);
- void resetClipIfNeeded();
-
- void updateClipScissorTest();
- void setScissor(const QRect &rect);
- void regenerateClip();
- void systemStateChanged();
- uint use_system_clip : 1;
-
- uint location(QGLEngineShaderManager::Uniform uniform)
- {
- return shaderManager->getUniformLocation(uniform);
- }
+ bool addOffset; // When enabled, adds a 0.49,0.49 offset to matrix in updateMatrix
+ GLfloat pmvMatrix[3][3];
+ GLfloat inverseScale;
- GLuint lastTexture;
+ GLuint lastTextureUsed;
bool needsSync;
bool inRenderText;
@@ -286,15 +282,11 @@ public:
QTriangulatingStroker stroker;
QDashedStrokeProcessor dasher;
- QTransform temporaryTransform;
QScopedPointer<QPixmapFilter> convolutionFilter;
QScopedPointer<QPixmapFilter> colorizeFilter;
QScopedPointer<QPixmapFilter> blurFilter;
- QScopedPointer<QPixmapFilter> animationBlurFilter;
- QScopedPointer<QPixmapFilter> fastBlurFilter;
QScopedPointer<QPixmapFilter> dropShadowFilter;
- QScopedPointer<QPixmapFilter> fastDropShadowFilter;
QSet<QVectorPath::CacheEntry *> pathCaches;
QVector<GLuint> unusedVBOSToClean;
diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
index 6082f49..395b8a3 100644
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
@@ -62,8 +62,14 @@ void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal *
endCap(cur);
}
int count = m_vertices.size();
- m_vertices.add(m_vertices.at(count-2));
- m_vertices.add(m_vertices.at(count-1));
+
+ // Copy the (x, y) values because QDataBuffer::add(const float& t)
+ // may resize the buffer, which will leave t pointing at the
+ // previous buffer's memory region if we don't copy first.
+ float x = m_vertices.at(count-2);
+ float y = m_vertices.at(count-1);
+ m_vertices.add(x);
+ m_vertices.add(y);
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 5ada125..466e851 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -127,18 +127,6 @@ Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
bool QGLExtensions::nvidiaFboNeedsFinish = false;
-#ifndef APIENTRY
-# define APIENTRY
-#endif
-typedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
- GLsizei, GLint, GLsizei, const GLvoid *);
-static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0;
-
-
-#ifndef APIENTRY
-#define APIENTRY
-#endif
-
Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
QGLSignalProxy *QGLSignalProxy::instance()
{
@@ -185,12 +173,12 @@ public:
#else
// We can't do this in the constructor for this object because it
// needs to be called *before* the QApplication constructor.
- // Also check for the FragmentProgram extension in conjunction with
+ // Also check for the FragmentShader extension in conjunction with
// the 2.0 version flag, to cover the case where we export the display
// from an old GL 1.1 server to a GL 2.x client. In that case we can't
// use GL 2.0.
if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
- && (QGLExtensions::glExtensions & QGLExtensions::FragmentProgram)
+ && (QGLExtensions::glExtensions & QGLExtensions::FragmentShader)
&& qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
engineType = QPaintEngine::OpenGL2;
else
@@ -409,8 +397,7 @@ static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz,
\i \link setDirectRendering() Direct rendering:\endlink Enabled.
\i \link setOverlay() Overlay:\endlink Disabled.
\i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
- \i \link setSampleBuffers() Multisample buffers:\endlink Enabled on
- OpenGL/ES 2.0, disabled on other platforms.
+ \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
\endlist
*/
@@ -1495,6 +1482,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
version_flags_cached = false;
version_flags = QGLFormat::OpenGL_Version_None;
current_fbo = 0;
+ default_fbo = 0;
active_engine = 0;
}
@@ -1886,118 +1874,42 @@ void QGLContextPrivate::cleanup()
{
}
-typedef QHash<QString, GLuint> QGLDDSCache;
-Q_GLOBAL_STATIC(QGLDDSCache, qgl_dds_cache)
-
/*!
\overload
- Reads the DirectDrawSurface (DDS) compressed file \a fileName and
- generates a 2D GL texture from it.
+ Reads the compressed texture file \a fileName and generates a 2D GL
+ texture from it.
- Only the DXT1, DXT3 and DXT5 DDS formats are supported.
+ This function can load DirectDrawSurface (DDS) textures in the
+ DXT1, DXT3 and DXT5 DDS formats if the \c GL_ARB_texture_compression
+ and \c GL_EXT_texture_compression_s3tc extensions are supported.
- Note that this will only work if the implementation supports the
- \c GL_ARB_texture_compression and \c GL_EXT_texture_compression_s3tc
- extensions.
+ Since 4.6.1, textures in the ETC1 format can be loaded if the
+ \c GL_OES_compressed_ETC1_RGB8_texture extension is supported
+ and the ETC1 texture has been encapsulated in the PVR container format.
+ Also, textures in the PVRTC2 and PVRTC4 formats can be loaded
+ if the \c GL_IMG_texture_compression_pvrtc extension is supported.
\sa deleteTexture()
*/
GLuint QGLContext::bindTexture(const QString &fileName)
{
- if (!qt_glCompressedTexImage2DARB) {
- qWarning("QGLContext::bindTexture(): The GL implementation does not support texture"
- "compression extensions.");
- return 0;
- }
-
- QGLDDSCache::const_iterator it = qgl_dds_cache()->constFind(fileName);
- if (it != qgl_dds_cache()->constEnd()) {
+ Q_D(QGLContext);
+ QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
+ QGLDDSCache::const_iterator it = dds_cache->constFind(fileName);
+ if (it != dds_cache->constEnd()) {
glBindTexture(GL_TEXTURE_2D, it.value());
return it.value();
}
- QFile f(fileName);
- f.open(QIODevice::ReadOnly);
-
- char tag[4];
- f.read(&tag[0], 4);
- if (strncmp(tag,"DDS ", 4) != 0) {
- qWarning("QGLContext::bindTexture(): not a DDS image file.");
- return 0;
- }
-
- DDSFormat ddsHeader;
- f.read((char *) &ddsHeader, sizeof(DDSFormat));
-
- if (!ddsHeader.dwLinearSize) {
- qWarning("QGLContext::bindTexture() DDS image size is not valid.");
- return 0;
- }
-
- int factor = 4;
- int bufferSize = 0;
- int blockSize = 16;
- GLenum format;
-
- switch(ddsHeader.ddsPixelFormat.dwFourCC) {
- case FOURCC_DXT1:
- format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- factor = 2;
- blockSize = 8;
- break;
- case FOURCC_DXT3:
- format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
- break;
- case FOURCC_DXT5:
- format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
- break;
- default:
- qWarning("QGLContext::bindTexture() DDS image format not supported.");
+ QGLTexture texture(this);
+ QSize size = texture.bindCompressedTexture(fileName);
+ if (!size.isValid())
return 0;
- }
-
- if (ddsHeader.dwMipMapCount > 1)
- bufferSize = ddsHeader.dwLinearSize * factor;
- else
- bufferSize = ddsHeader.dwLinearSize;
-
- GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte));
- f.seek(ddsHeader.dwSize + 4);
- f.read((char *) pixels, bufferSize);
- f.close();
-
- GLuint tx_id;
- glGenTextures(1, &tx_id);
- glBindTexture(GL_TEXTURE_2D, tx_id);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
- int size;
- int offset = 0;
- int w = ddsHeader.dwWidth;
- int h = ddsHeader.dwHeight;
-
- // load mip-maps
- for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) {
- if (w == 0) w = 1;
- if (h == 0) h = 1;
-
- size = ((w+3)/4) * ((h+3)/4) * blockSize;
- qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0,
- size, pixels + offset);
- offset += size;
-
- // half size for each mip-map level
- w = w/2;
- h = h/2;
- }
- free(pixels);
-
- qgl_dds_cache()->insert(fileName, tx_id);
- return tx_id;
+ dds_cache->insert(fileName, texture.id);
+ return texture.id;
}
static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format)
@@ -2151,6 +2063,29 @@ QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
// #define QGL_BIND_TEXTURE_DEBUG
+// map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout
+static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
+ || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
+ }
+ }
+}
+
QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint internalFormat,
const qint64 key, QGLContext::BindOptions options)
{
@@ -2303,24 +2238,16 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
// 32 in the switch above is for the RGB16 case, where we set
// the format to GL_RGB
Q_ASSERT(img.depth() == 32);
- const int width = img.width();
- const int height = img.height();
-
- if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
- || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
- for (int i=0; i < height; ++i) {
- uint *p = (uint *) img.scanLine(i);
- for (int x=0; x<width; ++x)
- p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
- }
- } else {
- for (int i=0; i < height; ++i) {
- uint *p = (uint *) img.scanLine(i);
- for (int x=0; x<width; ++x)
- p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
- }
- }
+ qgl_byteSwapImage(img, pixel_type);
}
+#ifdef QT_OPENGL_ES
+ // OpenGL/ES requires that the internal and external formats be identical.
+ // This is typically used to convert GL_RGBA into GL_BGRA.
+ // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA.
+ internalFormat = externalFormat;
+ if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV)
+ pixel_type = GL_UNSIGNED_BYTE;
+#endif
#ifdef QGL_BIND_TEXTURE_DEBUG
printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
img.format(), externalFormat, internalFormat, pixel_type);
@@ -2592,17 +2519,20 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, Q
*/
void QGLContext::deleteTexture(GLuint id)
{
+ Q_D(QGLContext);
+
if (QGLTextureCache::instance()->remove(this, id))
return;
// check the DDS cache if the texture wasn't found in the pixmap/image
// cache
- QList<QString> ddsKeys = qgl_dds_cache()->keys();
+ QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
+ QList<QString> ddsKeys = dds_cache->keys();
for (int i = 0; i < ddsKeys.size(); ++i) {
- GLuint texture = qgl_dds_cache()->value(ddsKeys.at(i));
+ GLuint texture = dds_cache->value(ddsKeys.at(i));
if (id == texture) {
glDeleteTextures(1, &texture);
- qgl_dds_cache()->remove(ddsKeys.at(i));
+ dds_cache->remove(ddsKeys.at(i));
return;
}
}
@@ -3880,6 +3810,11 @@ bool QGLWidget::event(QEvent *e)
}
#if defined(QT_OPENGL_ES)
+ // A re-parent is likely to destroy the X11 window and re-create it. It is important
+ // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
+ if (e->type() == QEvent::ParentAboutToChange)
+ d->glcx->d_func()->destroyEglSurfaceForDevice();
+
if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
// The window may have been re-created during re-parent or state change - if so, the EGL
// surface will need to be re-created.
@@ -4170,7 +4105,7 @@ void QGLWidget::qglColor(const QColor& c) const
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
if (ctx->format().rgba())
- glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
+ glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
int i = d->cmap.find(c.rgb());
if (i < 0)
@@ -4367,6 +4302,7 @@ static void qt_save_gl_state()
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDisable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
@@ -4420,6 +4356,10 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
\note This function clears the stencil buffer.
\note This function is not supported on OpenGL/ES systems.
+
+ \note This function temporarily disables depth-testing when the
+ text is drawn.
+
\l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
*/
@@ -4510,6 +4450,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
have the labels move with the model as it is rotated etc.
\note This function is not supported on OpenGL/ES systems.
+
+ \note If depth testing is enabled before this function is called,
+ then the drawn text will be depth-tested against the models that
+ have already been drawn in the scene. Use \c{glDisable(GL_DEPTH_TEST)}
+ before calling this function to annotate the models without
+ depth-testing the text.
+
\l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
*/
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int)
@@ -4899,63 +4846,67 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent,
void QGLExtensions::init_extensions()
{
- QList<QByteArray> extensions = QByteArray(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))).split(' ');
- if (extensions.contains("GL_ARB_texture_rectangle"))
+ QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+
+ if (extensions.match("GL_ARB_texture_rectangle"))
glExtensions |= TextureRectangle;
- if (extensions.contains("GL_ARB_multisample"))
+ if (extensions.match("GL_ARB_multisample"))
glExtensions |= SampleBuffers;
- if (extensions.contains("GL_SGIS_generate_mipmap"))
+ if (extensions.match("GL_SGIS_generate_mipmap"))
glExtensions |= GenerateMipmap;
- if (extensions.contains("GL_EXT_texture_compression_s3tc"))
+ if (extensions.match("GL_ARB_texture_compression"))
glExtensions |= TextureCompression;
- if (extensions.contains("GL_ARB_fragment_program"))
+ if (extensions.match("GL_EXT_texture_compression_s3tc"))
+ glExtensions |= DDSTextureCompression;
+ if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture"))
+ glExtensions |= ETC1TextureCompression;
+ if (extensions.match("GL_IMG_texture_compression_pvrtc"))
+ glExtensions |= PVRTCTextureCompression;
+ if (extensions.match("GL_ARB_fragment_program"))
glExtensions |= FragmentProgram;
- if (extensions.contains("GL_ARB_texture_mirrored_repeat"))
+ if (extensions.match("GL_ARB_fragment_shader"))
+ glExtensions |= FragmentShader;
+ if (extensions.match("GL_ARB_texture_mirrored_repeat"))
glExtensions |= MirroredRepeat;
- if (extensions.contains("GL_EXT_framebuffer_object"))
+ if (extensions.match("GL_EXT_framebuffer_object"))
glExtensions |= FramebufferObject;
- if (extensions.contains("GL_EXT_stencil_two_side"))
+ if (extensions.match("GL_EXT_stencil_two_side"))
glExtensions |= StencilTwoSide;
- if (extensions.contains("GL_EXT_stencil_wrap"))
+ if (extensions.match("GL_EXT_stencil_wrap"))
glExtensions |= StencilWrap;
- if (extensions.contains("GL_EXT_packed_depth_stencil"))
+ if (extensions.match("GL_EXT_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
- if (extensions.contains("GL_NV_float_buffer"))
+ if (extensions.match("GL_NV_float_buffer"))
glExtensions |= NVFloatBuffer;
- if (extensions.contains("GL_ARB_pixel_buffer_object"))
+ if (extensions.match("GL_ARB_pixel_buffer_object"))
glExtensions |= PixelBufferObject;
#if defined(QT_OPENGL_ES_2)
glExtensions |= FramebufferObject;
glExtensions |= GenerateMipmap;
+ glExtensions |= FragmentShader;
#endif
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
- if (extensions.contains("GL_OES_framebuffer_object"))
+ if (extensions.match("GL_OES_framebuffer_object"))
glExtensions |= FramebufferObject;
#endif
#if defined(QT_OPENGL_ES)
- if (extensions.contains("GL_OES_packed_depth_stencil"))
+ if (extensions.match("GL_OES_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
#endif
- if (extensions.contains("GL_ARB_framebuffer_object")) {
+ if (extensions.match("GL_ARB_framebuffer_object")) {
// ARB_framebuffer_object also includes EXT_framebuffer_blit.
glExtensions |= FramebufferObject;
glExtensions |= FramebufferBlit;
}
- if (extensions.contains("GL_EXT_framebuffer_blit"))
+ if (extensions.match("GL_EXT_framebuffer_blit"))
glExtensions |= FramebufferBlit;
- if (extensions.contains("GL_ARB_texture_non_power_of_two"))
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
glExtensions |= NPOTTextures;
- if (extensions.contains("GL_EXT_bgra"))
+ if (extensions.match("GL_EXT_bgra"))
glExtensions |= BGRATextureFormat;
-
-
- QGLContext cx(QGLFormat::defaultFormat());
- if (glExtensions & TextureCompression) {
- qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
- }
}
/*
@@ -5111,4 +5062,341 @@ void QGLSharedResourceGuard::setContext(const QGLContext *context)
}
}
+QSize QGLTexture::bindCompressedTexture
+ (const QString& fileName, const char *format)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly))
+ return QSize();
+ QByteArray contents = file.readAll();
+ file.close();
+ return bindCompressedTexture
+ (contents.constData(), contents.size(), format);
+}
+
+// PVR header format for container files that store textures compressed
+// with the ETC1, PVRTC2, and PVRTC4 encodings. Format information from the
+// PowerVR SDK at http://www.imgtec.com/powervr/insider/powervr-sdk.asp
+// "PVRTexTool Reference Manual, version 1.11f".
+struct PvrHeader
+{
+ quint32 headerSize;
+ quint32 height;
+ quint32 width;
+ quint32 mipMapCount;
+ quint32 flags;
+ quint32 dataSize;
+ quint32 bitsPerPixel;
+ quint32 redMask;
+ quint32 greenMask;
+ quint32 blueMask;
+ quint32 alphaMask;
+ quint32 magic;
+ quint32 surfaceCount;
+};
+
+#define PVR_MAGIC 0x21525650 // "PVR!" in little-endian
+
+#define PVR_FORMAT_MASK 0x000000FF
+#define PVR_FORMAT_PVRTC2 0x00000018
+#define PVR_FORMAT_PVRTC4 0x00000019
+#define PVR_FORMAT_ETC1 0x00000036
+
+#define PVR_HAS_MIPMAPS 0x00000100
+#define PVR_TWIDDLED 0x00000200
+#define PVR_NORMAL_MAP 0x00000400
+#define PVR_BORDER_ADDED 0x00000800
+#define PVR_CUBE_MAP 0x00001000
+#define PVR_FALSE_COLOR_MIPMAPS 0x00002000
+#define PVR_VOLUME_TEXTURE 0x00004000
+#define PVR_ALPHA_IN_TEXTURE 0x00008000
+#define PVR_VERTICAL_FLIP 0x00010000
+
+#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif
+
+#ifndef GL_ETC1_RGB8_OES
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif
+
+bool QGLTexture::canBindCompressedTexture
+ (const char *buf, int len, const char *format, bool *hasAlpha)
+{
+ if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) {
+ // Compressed texture loading only supported on little-endian
+ // systems such as x86 and ARM at the moment.
+ return false;
+ }
+ if (!format) {
+ // Auto-detect the format from the header.
+ if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) {
+ *hasAlpha = true;
+ return true;
+ } else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) {
+ const PvrHeader *pvrHeader =
+ reinterpret_cast<const PvrHeader *>(buf);
+ *hasAlpha = (pvrHeader->alphaMask != 0);
+ return true;
+ }
+ } else {
+ // Validate the format against the header.
+ if (!qstricmp(format, "DDS")) {
+ if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) {
+ *hasAlpha = true;
+ return true;
+ }
+ } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) {
+ if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) {
+ const PvrHeader *pvrHeader =
+ reinterpret_cast<const PvrHeader *>(buf);
+ *hasAlpha = (pvrHeader->alphaMask != 0);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+#define ctx QGLContext::currentContext()
+
+QSize QGLTexture::bindCompressedTexture
+ (const char *buf, int len, const char *format)
+{
+ if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) {
+ // Compressed texture loading only supported on little-endian
+ // systems such as x86 and ARM at the moment.
+ return QSize();
+ }
+#if !defined(QT_OPENGL_ES)
+ if (!glCompressedTexImage2D) {
+ if (!(QGLExtensions::glExtensions & QGLExtensions::TextureCompression)) {
+ qWarning("QGLContext::bindTexture(): The GL implementation does "
+ "not support texture compression extensions.");
+ return QSize();
+ }
+ glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
+ if (!glCompressedTexImage2D) {
+ qWarning("QGLContext::bindTexture(): could not resolve "
+ "glCompressedTexImage2DARB.");
+ return QSize();
+ }
+ }
+#endif
+ if (!format) {
+ // Auto-detect the format from the header.
+ if (len >= 4 && !qstrncmp(buf, "DDS ", 4))
+ return bindCompressedTextureDDS(buf, len);
+ else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4))
+ return bindCompressedTexturePVR(buf, len);
+ } else {
+ // Validate the format against the header.
+ if (!qstricmp(format, "DDS")) {
+ if (len >= 4 && !qstrncmp(buf, "DDS ", 4))
+ return bindCompressedTextureDDS(buf, len);
+ } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) {
+ if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4))
+ return bindCompressedTexturePVR(buf, len);
+ }
+ }
+ return QSize();
+}
+
+QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len)
+{
+ // We only support 2D texture loading at present.
+ if (target != GL_TEXTURE_2D)
+ return QSize();
+
+ // Bail out if the necessary extension is not present.
+ if (!(QGLExtensions::glExtensions & QGLExtensions::DDSTextureCompression)) {
+ qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
+ return QSize();
+ }
+
+ const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
+ if (!ddsHeader->dwLinearSize) {
+ qWarning("QGLContext::bindTexture(): DDS image size is not valid.");
+ return QSize();
+ }
+
+ int blockSize = 16;
+ GLenum format;
+
+ switch(ddsHeader->ddsPixelFormat.dwFourCC) {
+ case FOURCC_DXT1:
+ format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ blockSize = 8;
+ break;
+ case FOURCC_DXT3:
+ format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ break;
+ case FOURCC_DXT5:
+ format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ break;
+ default:
+ qWarning("QGLContext::bindTexture(): DDS image format not supported.");
+ return QSize();
+ }
+
+ const GLubyte *pixels =
+ reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4);
+
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ int size;
+ int offset = 0;
+ int available = len - int(ddsHeader->dwSize + 4);
+ int w = ddsHeader->dwWidth;
+ int h = ddsHeader->dwHeight;
+
+ // load mip-maps
+ for(int i = 0; i < (int) ddsHeader->dwMipMapCount; ++i) {
+ if (w == 0) w = 1;
+ if (h == 0) h = 1;
+
+ size = ((w+3)/4) * ((h+3)/4) * blockSize;
+ if (size > available)
+ break;
+ glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0,
+ size, pixels + offset);
+ offset += size;
+ available -= size;
+
+ // half size for each mip-map level
+ w = w/2;
+ h = h/2;
+ }
+
+ // DDS images are not inverted.
+ options &= ~QGLContext::InvertedYBindOption;
+
+ return QSize(ddsHeader->dwWidth, ddsHeader->dwHeight);
+}
+
+QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
+{
+ // We only support 2D texture loading at present. Cube maps later.
+ if (target != GL_TEXTURE_2D)
+ return QSize();
+
+ // Determine which texture format we will be loading.
+ const PvrHeader *pvrHeader = reinterpret_cast<const PvrHeader *>(buf);
+ GLenum textureFormat;
+ quint32 minWidth, minHeight;
+ switch (pvrHeader->flags & PVR_FORMAT_MASK) {
+ case PVR_FORMAT_PVRTC2:
+ if (pvrHeader->alphaMask)
+ textureFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
+ else
+ textureFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
+ minWidth = 16;
+ minHeight = 8;
+ break;
+
+ case PVR_FORMAT_PVRTC4:
+ if (pvrHeader->alphaMask)
+ textureFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+ else
+ textureFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
+ minWidth = 8;
+ minHeight = 8;
+ break;
+
+ case PVR_FORMAT_ETC1:
+ textureFormat = GL_ETC1_RGB8_OES;
+ minWidth = 4;
+ minHeight = 4;
+ break;
+
+ default:
+ qWarning("QGLContext::bindTexture(): PVR image format 0x%x not supported.", int(pvrHeader->flags & PVR_FORMAT_MASK));
+ return QSize();
+ }
+
+ // Bail out if the necessary extension is not present.
+ if (textureFormat == GL_ETC1_RGB8_OES) {
+ if (!(QGLExtensions::glExtensions &
+ QGLExtensions::ETC1TextureCompression)) {
+ qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
+ return QSize();
+ }
+ } else {
+ if (!(QGLExtensions::glExtensions &
+ QGLExtensions::PVRTCTextureCompression)) {
+ qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
+ return QSize();
+ }
+ }
+
+ // Boundary check on the buffer size.
+ quint32 bufferSize = pvrHeader->headerSize + pvrHeader->dataSize;
+ if (bufferSize > quint32(len)) {
+ qWarning("QGLContext::bindTexture(): PVR image size is not valid.");
+ return QSize();
+ }
+
+ // Create the texture.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+ if (pvrHeader->mipMapCount) {
+ if ((options & QGLContext::LinearFilteringBindOption) != 0) {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ }
+ } else if ((options & QGLContext::LinearFilteringBindOption) != 0) {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ // Load the compressed mipmap levels.
+ const GLubyte *buffer =
+ reinterpret_cast<const GLubyte *>(buf + pvrHeader->headerSize);
+ bufferSize = pvrHeader->dataSize;
+ quint32 level = 0;
+ quint32 width = pvrHeader->width;
+ quint32 height = pvrHeader->height;
+ while (bufferSize > 0 && level < pvrHeader->mipMapCount) {
+ quint32 size =
+ (qMax(width, minWidth) * qMax(height, minHeight) *
+ pvrHeader->bitsPerPixel) / 8;
+ if (size > bufferSize)
+ break;
+ glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat,
+ GLsizei(width), GLsizei(height), 0,
+ GLsizei(size), buffer);
+ width /= 2;
+ height /= 2;
+ buffer += size;
+ ++level;
+ }
+
+ // Restore the default pixel alignment for later texture uploads.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ // Set the invert flag for the texture. The "vertical flip"
+ // flag in PVR is the opposite sense to our sense of inversion.
+ if ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0)
+ options &= ~QGLContext::InvertedYBindOption;
+ else
+ options |= QGLContext::InvertedYBindOption;
+
+ return QSize(pvrHeader->width, pvrHeader->height);
+}
+
+#undef ctx
+
QT_END_NAMESPACE
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 079953f..2076c46 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -546,6 +546,7 @@ private:
friend class QGLPixelBuffer;
friend class QGLPixelBufferPrivate;
friend class QGLContext;
+ friend class QGLContextPrivate;
friend class QGLOverlayWidget;
friend class QOpenGLPaintEngine;
friend class QGLPaintDevice;
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index fbf0349..839e8eb 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -142,19 +142,7 @@ void QGLContext::reset()
d->cleanup();
doneCurrent();
if (d->eglContext) {
- if (d->eglSurface != EGL_NO_SURFACE) {
-#ifdef Q_WS_X11
- // Make sure we don't call eglDestroySurface on a surface which
- // was created for a different winId:
- if (d->paintDevice->devType() == QInternal::Widget) {
- QGLWidget* w = static_cast<QGLWidget*>(d->paintDevice);
-
- if (w->d_func()->eglSurfaceWindowId == w->winId())
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
- } else
-#endif
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
- }
+ d->destroyEglSurfaceForDevice();
delete d->eglContext;
}
d->eglContext = 0;
@@ -198,6 +186,26 @@ void QGLContext::swapBuffers() const
d->eglContext->swapBuffers(d->eglSurface);
}
+void QGLContextPrivate::destroyEglSurfaceForDevice()
+{
+ if (eglSurface != EGL_NO_SURFACE) {
+#ifdef Q_WS_X11
+ // Make sure we don't call eglDestroySurface on a surface which
+ // was created for a different winId:
+ if (paintDevice->devType() == QInternal::Widget) {
+ QGLWidget* w = static_cast<QGLWidget*>(paintDevice);
+
+ if (w->d_func()->eglSurfaceWindowId == w->winId())
+ eglDestroySurface(eglContext->display(), eglSurface);
+ else
+ qWarning("WARNING: Potential EGL surface leak!");
+ } else
+#endif
+ eglDestroySurface(eglContext->display(), eglSurface);
+ eglSurface = EGL_NO_SURFACE;
+ }
+}
+
void QGLWidget::setMouseTracking(bool enable)
{
QWidget::setMouseTracking(enable);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 8e472e5..99c0f33 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -133,9 +133,6 @@ public:
: ref(1)
{
opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering | QGL::StencilBuffer;
-#if defined(QT_OPENGL_ES_2)
- opts |= QGL::SampleBuffers;
-#endif
pln = 0;
depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1;
numSamples = -1;
@@ -222,6 +219,8 @@ public:
class QGLContextResource;
class QGLSharedResourceGuard;
+typedef QHash<QString, GLuint> QGLDDSCache;
+
// QGLContextPrivate has the responsibility of creating context groups.
// QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy
// context groups when needed.
@@ -246,6 +245,7 @@ private:
QHash<QGLContextResource *, void *> m_resources;
QGLSharedResourceGuard *m_guards; // double-linked list of active guards.
QAtomicInt m_refs;
+ QGLDDSCache m_dds_cache;
void cleanupResources(const QGLContext *ctx);
@@ -288,6 +288,7 @@ public:
#if defined(QT_OPENGL_ES)
QEglContext *eglContext;
EGLSurface eglSurface;
+ void destroyEglSurfaceForDevice();
#elif defined(Q_WS_X11) || defined(Q_WS_MAC)
void* cx;
#endif
@@ -328,6 +329,7 @@ public:
GLint max_texture_size;
GLuint current_fbo;
+ GLuint default_fbo;
QPaintEngine *active_engine;
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
@@ -376,7 +378,11 @@ public:
PixelBufferObject = 0x00000800,
FramebufferBlit = 0x00001000,
NPOTTextures = 0x00002000,
- BGRATextureFormat = 0x00004000
+ BGRATextureFormat = 0x00004000,
+ DDSTextureCompression = 0x00008000,
+ ETC1TextureCompression = 0x00010000,
+ PVRTCTextureCompression = 0x00020000,
+ FragmentShader = 0x00040000
};
Q_DECLARE_FLAGS(Extensions, Extension)
@@ -389,7 +395,7 @@ public:
Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
-class Q_AUTOTEST_EXPORT QGLShareRegister
+class Q_OPENGL_EXPORT QGLShareRegister
{
public:
QGLShareRegister() {}
@@ -481,6 +487,14 @@ public:
QPixmapData* boundPixmap;
#endif
+ bool canBindCompressedTexture
+ (const char *buf, int len, const char *format, bool *hasAlpha);
+ QSize bindCompressedTexture
+ (const QString& fileName, const char *format = 0);
+ QSize bindCompressedTexture
+ (const char *buf, int len, const char *format = 0);
+ QSize bindCompressedTextureDDS(const char *buf, int len);
+ QSize bindCompressedTexturePVR(const char *buf, int len);
};
class QGLTextureCache {
@@ -517,7 +531,8 @@ bool qt_gl_preferGL2Engine();
inline GLenum qt_gl_preferredTextureFormat()
{
- return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA;
+ return (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
+ ? GL_BGRA : GL_RGBA;
}
inline GLenum qt_gl_preferredTextureTarget()
@@ -596,6 +611,49 @@ private:
friend class QGLContextGroup;
};
+
+// This class can be used to match GL extensions with doing any mallocs. The
+// class assumes that the GL extension string ends with a space character,
+// which it should do on all conformant platforms. Create the object and pass
+// in a pointer to the extension string, then call match() on each extension
+// that should be matched. The match() function takes the extension name
+// *without* the terminating space character as input.
+
+class QGLExtensionMatcher
+{
+public:
+ QGLExtensionMatcher(const char *str)
+ : gl_extensions(str), gl_extensions_length(qstrlen(str))
+ {}
+
+ bool match(const char *str) {
+ int str_length = qstrlen(str);
+ const char *extensions = gl_extensions;
+ int extensions_length = gl_extensions_length;
+
+ while (1) {
+ // the total length that needs to be matched is the str_length +
+ // the space character that terminates the extension name
+ if (extensions_length < str_length + 1)
+ return false;
+ if (qstrncmp(extensions, str, str_length) == 0 && extensions[str_length] == ' ')
+ return true;
+
+ int split_pos = 0;
+ while (split_pos < extensions_length && extensions[split_pos] != ' ')
+ ++split_pos;
+ ++split_pos; // added for the terminating space character
+ extensions += split_pos;
+ extensions_length -= split_pos;
+ }
+ return false;
+ }
+
+private:
+ const char *gl_extensions;
+ int gl_extensions_length;
+};
+
QT_END_NAMESPACE
#endif // QGL_P_H
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index a037282..9c3fc79 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -343,8 +343,8 @@ void* qglx_getProcAddress(const char* procName)
static bool triedResolvingGlxGetProcAddress = false;
if (!triedResolvingGlxGetProcAddress) {
triedResolvingGlxGetProcAddress = true;
- QList<QByteArray> glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' ');
- if (glxExt.contains("GLX_ARB_get_proc_address")) {
+ QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
+ if (extensions.match("GLX_ARB_get_proc_address")) {
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
void *handle = dlopen(NULL, RTLD_LAZY);
if (handle) {
@@ -523,8 +523,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
if (!d->gpm)
return false;
}
- QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' ');
- if (glxExt.contains("GLX_SGI_video_sync")) {
+ QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
+ if (extensions.match("GLX_SGI_video_sync")) {
if (d->glFormat.swapInterval() == -1)
d->glFormat.setSwapInterval(0);
} else {
@@ -630,8 +630,8 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
static bool useTranspExt = false;
static bool useTranspExtChecked = false;
if (f.plane() && !useTranspExtChecked && d->paintDevice) {
- QByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- useTranspExt = estr.contains("GLX_EXT_visual_info");
+ QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
+ useTranspExt = extensions.match("GLX_EXT_visual_info");
//# (A bit simplistic; that could theoretically be a substring)
if (useTranspExt) {
QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
@@ -875,8 +875,8 @@ void QGLContext::swapBuffers() const
static bool resolved = false;
if (!resolved) {
const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' ');
- if (glxExt.contains("GLX_SGI_video_sync")) {
+ QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
+ if (extensions.match("GLX_SGI_video_sync")) {
glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
}
@@ -1107,8 +1107,8 @@ void *QGLContext::getProcAddress(const QString &proc) const
if (resolved && !glXGetProcAddressARB)
return 0;
if (!glXGetProcAddressARB) {
- QList<QByteArray> glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' ');
- if (glxExt.contains("GLX_ARB_get_proc_address")) {
+ QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
+ if (extensions.match("GLX_ARB_get_proc_address")) {
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
void *handle = dlopen(NULL, RTLD_LAZY);
if (handle) {
@@ -1609,8 +1609,8 @@ static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
return false; // Can't use TFP without NPOT
}
const QX11Info *xinfo = qt_x11Info(paintDevice);
- QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' ');
- if (glxExt.contains("GLX_EXT_texture_from_pixmap")) {
+ QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
+ if (extensions.match("GLX_EXT_texture_from_pixmap")) {
glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
}
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index b51c239..19026b3 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -63,6 +63,7 @@ void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)
props.setPixelFormat(static_cast<QImage *>(device)->format());
}
+// Chooses the EGL config and creates the EGL context
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
Q_D(QGLContext);
@@ -73,56 +74,74 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
int devType = device()->devType();
// Get the display and initialize it.
- d->eglContext = new QEglContext();
- d->eglContext->setApi(QEgl::OpenGL);
- if (!d->eglContext->openDisplay(device())) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
+ if (d->eglContext == 0) {
+ d->eglContext = new QEglContext();
+ d->eglContext->setApi(QEgl::OpenGL);
+ if (!d->eglContext->openDisplay(device())) {
+ delete d->eglContext;
+ d->eglContext = 0;
+ return false;
+ }
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- qt_egl_set_format(configProps, devType, d->glFormat);
- qt_egl_add_platform_config(configProps, device());
- configProps.setRenderableType(QEgl::OpenGL);
-
- QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat;
- if (device()->depth() == 16) {
- configProps.setValue(EGL_RED_SIZE, 5);
- configProps.setValue(EGL_GREEN_SIZE, 6);
- configProps.setValue(EGL_BLUE_SIZE, 5);
- configProps.setValue(EGL_ALPHA_SIZE, 0);
- matchType = QEgl::ExactPixelFormat;
- }
- configProps.setRenderableType(QEgl::OpenGL);
+ // Construct the configuration we need for this surface.
+ QEglProperties configProps;
+ qt_egl_set_format(configProps, devType, d->glFormat);
+ qt_egl_add_platform_config(configProps, device());
+ configProps.setRenderableType(QEgl::OpenGL);
+
+#if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE
+ if (device()->depth() == 16 && configProps.value(EGL_ALPHA_SIZE) <= 0) {
+ qDebug("Setting EGL_BUFFER_SIZE to 16");
+ configProps.setValue(EGL_BUFFER_SIZE, 16);
+ configProps.setValue(EGL_ALPHA_SIZE, 0);
+ }
- // Search for a matching configuration, reducing the complexity
- // each time until we get something that matches.
- if (!d->eglContext->chooseConfig(configProps, matchType)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
+ if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
+ delete d->eglContext;
+ d->eglContext = 0;
+ return false;
+ }
+#else
+ QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat;
+ if ((device()->depth() == 16) && configProps.value(EGL_ALPHA_SIZE) == 0) {
+ configProps.setValue(EGL_RED_SIZE, 5);
+ configProps.setValue(EGL_GREEN_SIZE, 6);
+ configProps.setValue(EGL_BLUE_SIZE, 5);
+ configProps.setValue(EGL_ALPHA_SIZE, 0);
+ matchType = QEgl::ExactPixelFormat;
+ }
- // Inform the higher layers about the actual format properties.
- qt_egl_update_format(*(d->eglContext), d->glFormat);
+ // Search for a matching configuration, reducing the complexity
+ // each time until we get something that matches.
+ if (!d->eglContext->chooseConfig(configProps, matchType)) {
+ delete d->eglContext;
+ d->eglContext = 0;
+ return false;
+ }
+#endif
- // Create a new context for the configuration.
- if (!d->eglContext->createContext
- (shareContext ? shareContext->d_func()->eglContext : 0)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
+// qDebug("QGLContext::chooseContext() - using EGL config %d:", d->eglContext->config());
+// qDebug() << QEglProperties(d->eglContext->config()).toString();
+
+ // Create a new context for the configuration.
+ if (!d->eglContext->createContext
+ (shareContext ? shareContext->d_func()->eglContext : 0)) {
+ delete d->eglContext;
+ d->eglContext = 0;
+ return false;
+ }
+ d->sharing = d->eglContext->isSharing();
+ if (d->sharing && shareContext)
+ const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
#if defined(EGL_VERSION_1_1)
- if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
- eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
+ if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
+ eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
#endif
+ }
+
+ // Inform the higher layers about the actual format properties.
+ qt_egl_update_format(*(d->eglContext), d->glFormat);
return true;
}
@@ -154,12 +173,21 @@ void QGLWidget::updateOverlayGL()
//handle overlay
}
+//#define QT_DEBUG_X11_VISUAL_SELECTION 1
+
bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual)
{
bool foundVisualIsArgb = useArgbVisual;
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("qt_egl_setup_x11_visual() - useArgbVisual=%d", useArgbVisual);
+#endif
+
memset(&vi, 0, sizeof(XVisualInfo));
+ EGLint eglConfigColorSize;
+ eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &eglConfigColorSize);
+
// Check to see if EGL is suggesting an appropriate visual id:
EGLint nativeVisualId;
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId);
@@ -177,7 +205,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
XRenderPictFormat *format;
format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual);
if (format->type == PictTypeDirect && format->direct.alphaMask) {
-// qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#endif
foundVisualIsArgb = true;
vi = *chosenVisualInfo;
}
@@ -189,8 +219,14 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
} else
#endif
{
-// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);
- vi = *chosenVisualInfo;
+ if (eglConfigColorSize == chosenVisualInfo->depth) {
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#endif
+ vi = *chosenVisualInfo;
+ } else
+ qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!",
+ nativeVisualId, chosenVisualInfo->depth, (int)config, eglConfigColorSize);
}
XFree(chosenVisualInfo);
}
@@ -222,7 +258,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
if (format->type == PictTypeDirect && format->direct.alphaMask) {
vi = matchingVisuals[i];
foundVisualIsArgb = true;
-// qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid);
+#endif
break;
}
}
@@ -246,24 +284,28 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
} else
qWarning(" - Falling back to X11 suggested depth (%d)", depth);
}
-// else
-// qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ else
+ qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);
+#endif
// Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-(
if (useArgbVisual)
foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444
}
-// qDebug("Visual Info:");
-// qDebug(" bits_per_rgb=%d", vi.bits_per_rgb);
-// qDebug(" red_mask=0x%x", vi.red_mask);
-// qDebug(" green_mask=0x%x", vi.green_mask);
-// qDebug(" blue_mask=0x%x", vi.blue_mask);
-// qDebug(" colormap_size=%d", vi.colormap_size);
-// qDebug(" c_class=%d", vi.c_class);
-// qDebug(" depth=%d", vi.depth);
-// qDebug(" screen=%d", vi.screen);
-// qDebug(" visualid=%d", vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Visual Info:");
+ qDebug(" bits_per_rgb=%d", vi.bits_per_rgb);
+ qDebug(" red_mask=0x%x", vi.red_mask);
+ qDebug(" green_mask=0x%x", vi.green_mask);
+ qDebug(" blue_mask=0x%x", vi.blue_mask);
+ qDebug(" colormap_size=%d", vi.colormap_size);
+ qDebug(" c_class=%d", vi.c_class);
+ qDebug(" depth=%d", vi.depth);
+ qDebug(" screen=%d", vi.screen);
+ qDebug(" visualid=%d", vi.visualid);
+#endif
return foundVisualIsArgb;
}
@@ -294,12 +336,14 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
// If the application has set WA_TranslucentBackground and not explicitly set
// the alpha buffer size to zero, modify the format so it have an alpha channel
QGLFormat& fmt = d->glcx->d_func()->glFormat;
- const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground);
+ const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground) || fmt.alpha();
if (tryArgbVisual && fmt.alphaBufferSize() == -1)
fmt.setAlphaBufferSize(1);
bool createFailed = false;
if (!d->glcx->isValid()) {
+ // Create the QGLContext here, which in turn chooses the EGL config
+ // and creates the EGL context:
if (!d->glcx->create(shareContext ? shareContext : oldcx))
createFailed = true;
}
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 3510765..62e216c 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -184,6 +184,10 @@ typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1,
typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
+// ARB_texture_compression
+typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
+ GLsizei, GLint, GLsizei, const GLvoid *);
+
QT_BEGIN_NAMESPACE
struct QGLExtensionFuncs
@@ -289,6 +293,11 @@ struct QGLExtensionFuncs
#endif
qt_glMapBufferARB = 0;
qt_glUnmapBufferARB = 0;
+
+#if !defined(QT_OPENGL_ES)
+ // Texture compression
+ qt_glCompressedTexImage2DARB = 0;
+#endif
}
@@ -397,6 +406,10 @@ struct QGLExtensionFuncs
_glMapBufferARB qt_glMapBufferARB;
_glUnmapBufferARB qt_glUnmapBufferARB;
+#if !defined(QT_OPENGL_ES)
+ // Texture compression
+ _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
+#endif
};
@@ -732,6 +745,10 @@ struct QGLExtensionFuncs
#define glClearDepth glClearDepthf
#endif
+#if !defined(QT_OPENGL_ES)
+#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
+#endif
+
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
bool qt_resolve_buffer_extensions(QGLContext *ctx);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index d79283e..4b5c30a 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -597,6 +597,12 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
the constructors that take a QGLFramebufferObject parameter, and set the
QGLFramebufferObject::samples() property to a non-zero value.
+ When painting to a QGLFramebufferObject using QPainter, the state of
+ the current GL context will be altered by the paint engine to reflect
+ its needs. Applications should not rely upon the GL state being reset
+ to its original conditions, particularly the current shader program,
+ GL viewport, texture units, and drawing modes.
+
For multisample framebuffer objects a color render buffer is created,
otherwise a texture with the specified texture target is created.
The color render buffer or texture will have the specified internal
@@ -899,8 +905,8 @@ bool QGLFramebufferObject::release()
#endif
if (current) {
- current->d_ptr->current_fbo = 0;
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ current->d_ptr->current_fbo = current->d_ptr->default_fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, current->d_ptr->default_fbo);
}
return true;
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index 2867de5..bcd90a5 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -89,6 +89,12 @@ void QGLPaintDevice::beginPaint()
ctx->d_ptr->current_fbo = m_thisFBO;
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
}
+
+ // Set the default fbo for the context to m_thisFBO so that
+ // if some raw GL code between beginNativePainting() and
+ // endNativePainting() calls QGLFramebufferObject::release(),
+ // painting will revert to the window surface's fbo.
+ ctx->d_ptr->default_fbo = m_thisFBO;
}
void QGLPaintDevice::ensureActiveTarget()
@@ -101,6 +107,8 @@ void QGLPaintDevice::ensureActiveTarget()
ctx->d_ptr->current_fbo = m_thisFBO;
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
}
+
+ ctx->d_ptr->default_fbo = m_thisFBO;
}
void QGLPaintDevice::endPaint()
@@ -111,6 +119,8 @@ void QGLPaintDevice::endPaint()
ctx->d_ptr->current_fbo = m_previousFBO;
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_previousFBO);
}
+
+ ctx->d_ptr->default_fbo = 0;
}
QGLFormat QGLPaintDevice::format() const
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index c478630..d4bcbe9 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -55,11 +55,17 @@
#include "qgl_p.h"
#include "private/qapplication_p.h"
+#include "private/qdrawhelper_p.h"
+#include "private/qmemrotate_p.h"
#include "private/qmath_p.h"
#include "qmath.h"
QT_BEGIN_NAMESPACE
+// qpixmapfilter.cpp
+void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
+QImage qt_halfScaled(const QImage &source);
+
void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
{
const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption));
@@ -102,48 +108,21 @@ private:
class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
- QGLPixmapBlurFilter(QGraphicsBlurEffect::BlurHints hints);
-
- void setUniforms(QGLShaderProgram *program);
-
- static QByteArray generateGaussianShader(int radius, bool singlePass = false, bool dropShadow = false);
+ QGLPixmapBlurFilter();
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-
-private:
-
- mutable QSize m_textureSize;
- mutable bool m_horizontalBlur;
- mutable bool m_singlePass;
- mutable bool m_animatedBlur;
-
- mutable qreal m_t;
- mutable QSize m_targetSize;
-
- mutable bool m_haveCached;
- mutable int m_cachedRadius;
- mutable QGraphicsBlurEffect::BlurHints m_hints;
};
class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapDropShadowFilter>
{
public:
- QGLPixmapDropShadowFilter(QGraphicsBlurEffect::BlurHints hints);
+ QGLPixmapDropShadowFilter();
void setUniforms(QGLShaderProgram *program);
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-
-private:
- mutable QSize m_textureSize;
- mutable bool m_horizontalBlur;
- mutable bool m_singlePass;
-
- mutable bool m_haveCached;
- mutable int m_cachedRadius;
- mutable QGraphicsBlurEffect::BlurHints m_hints;
};
extern QGLWidget *qt_gl_share_widget();
@@ -158,31 +137,14 @@ QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *pr
return d->colorizeFilter.data();
case QPixmapFilter::BlurFilter: {
- const QPixmapBlurFilter *proto = static_cast<const QPixmapBlurFilter *>(prototype);
- if (proto->blurHints() & QGraphicsBlurEffect::AnimationHint) {
- if (!d->animationBlurFilter)
- d->animationBlurFilter.reset(new QGLPixmapBlurFilter(proto->blurHints()));
- return d->animationBlurFilter.data();
- }
- if ((proto->blurHints() & QGraphicsBlurEffect::QualityHint) && proto->radius() > 5) {
- if (!d->blurFilter)
- d->blurFilter.reset(new QGLPixmapBlurFilter(QGraphicsBlurEffect::QualityHint));
- return d->blurFilter.data();
- }
- if (!d->fastBlurFilter)
- d->fastBlurFilter.reset(new QGLPixmapBlurFilter(QGraphicsBlurEffect::PerformanceHint));
- return d->fastBlurFilter.data();
+ if (!d->blurFilter)
+ d->blurFilter.reset(new QGLPixmapBlurFilter());
+ return d->blurFilter.data();
}
case QPixmapFilter::DropShadowFilter: {
- const QPixmapDropShadowFilter *proto = static_cast<const QPixmapDropShadowFilter *>(prototype);
- if (proto->blurRadius() <= 5) {
- if (!d->fastDropShadowFilter)
- d->fastDropShadowFilter.reset(new QGLPixmapDropShadowFilter(QGraphicsBlurEffect::PerformanceHint));
- return d->fastDropShadowFilter.data();
- }
if (!d->dropShadowFilter)
- d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter(QGraphicsBlurEffect::QualityHint));
+ d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter());
return d->dropShadowFilter.data();
}
@@ -311,59 +273,43 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos
return true;
}
-static const char *qt_gl_texture_sampling_helper =
- "lowp float texture2DAlpha(lowp sampler2D src, highp vec2 srcCoords) {\n"
- " return texture2D(src, srcCoords).a;\n"
- "}\n";
-
-QGLPixmapBlurFilter::QGLPixmapBlurFilter(QGraphicsBlurEffect::BlurHints hints)
- : m_animatedBlur(false)
- , m_haveCached(false)
- , m_cachedRadius(0)
- , m_hints(hints)
-{
-}
-
-// should be even numbers as they will be divided by two
-static const int qCachedBlurLevels[] = { 6, 14, 30 };
-static const int qNumCachedBlurTextures = sizeof(qCachedBlurLevels) / sizeof(*qCachedBlurLevels);
-static const int qMaxCachedBlurLevel = qCachedBlurLevels[qNumCachedBlurTextures - 1];
-
-static qreal qLogBlurLevel(int level)
+QGLPixmapBlurFilter::QGLPixmapBlurFilter()
{
- static bool initialized = false;
- static qreal logBlurLevelCache[qNumCachedBlurTextures];
- if (!initialized) {
- for (int i = 0; i < qNumCachedBlurTextures; ++i)
- logBlurLevelCache[i] = qLn(qCachedBlurLevels[i]);
- initialized = true;
- }
- return logBlurLevelCache[level];
}
class QGLBlurTextureInfo
{
public:
- QGLBlurTextureInfo(QSize size, GLuint textureIds[])
- : m_size(size)
+ QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r)
+ : m_texture(tex)
+ , m_radius(r)
{
- for (int i = 0; i < qNumCachedBlurTextures; ++i)
- m_textureIds[i] = textureIds[i];
+ m_paddedImage << image;
}
~QGLBlurTextureInfo()
{
- glDeleteTextures(qNumCachedBlurTextures, m_textureIds);
+ glDeleteTextures(1, &m_texture);
}
- QSize size() const { return m_size; }
- GLuint textureId(int i) const { return m_textureIds[i]; }
+ QImage paddedImage(int scaleLevel = 0) const;
+ GLuint texture() const { return m_texture; }
+ qreal radius() const { return m_radius; }
private:
- GLuint m_textureIds[qNumCachedBlurTextures];
- QSize m_size;
+ mutable QList<QImage> m_paddedImage;
+ GLuint m_texture;
+ qreal m_radius;
};
+QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const
+{
+ for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i)
+ m_paddedImage << qt_halfScaled(m_paddedImage.at(i));
+
+ return m_paddedImage.at(scaleLevel);
+}
+
class QGLBlurTextureCache : public QObject
{
public:
@@ -373,7 +319,6 @@ public:
~QGLBlurTextureCache();
QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
- bool fitsInCache(const QPixmap &pixmap) const;
bool hasBlurTextureInfo(const QPixmap &pixmap) const;
void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info);
void clearBlurTextureInfo(const QPixmap &pixmap);
@@ -458,12 +403,7 @@ void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTe
if (timerId)
killTimer(timerId);
- timerId = startTimer(1000);
-}
-
-bool QGLBlurTextureCache::fitsInCache(const QPixmap &pixmap) const
-{
- return pixmap.width() * pixmap.height() <= cache.maxCost();
+ timerId = startTimer(8000);
}
void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap)
@@ -474,567 +414,217 @@ void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap)
}
}
-static const char *qt_gl_interpolate_filter =
- "uniform lowp float interpolationValue;"
- "uniform lowp sampler2D interpolateTarget;"
- "uniform highp vec4 interpolateMapping;"
- "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
- "{"
- " return mix(texture2D(interpolateTarget, interpolateMapping.xy + interpolateMapping.zw * srcCoords),"
- " texture2D(src, srcCoords), interpolationValue);"
- "}";
+static const int qAnimatedBlurLevelIncrement = 16;
+static const int qMaxBlurHalfScaleLevel = 1;
-static void initializeTexture(GLuint id, int width, int height)
+static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA)
{
- glBindTexture(GL_TEXTURE_2D, id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_2D, 0);
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format,
+ GL_UNSIGNED_BYTE, 0);
+ return texture;
}
-bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
+static inline uint nextMultiple(uint x, uint multiplier)
{
- QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this);
-
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
-
- if ((m_hints & QGraphicsBlurEffect::AnimationHint) && blurTextureCache->fitsInCache(src)) {
- QRect targetRect = src.rect().adjusted(-qMaxCachedBlurLevel, -qMaxCachedBlurLevel, qMaxCachedBlurLevel, qMaxCachedBlurLevel);
- // ensure even dimensions (going to divide by two)
- targetRect.setWidth((targetRect.width() + 1) & ~1);
- targetRect.setHeight((targetRect.height() + 1) & ~1);
-
- QGLBlurTextureInfo *info = 0;
- if (blurTextureCache->hasBlurTextureInfo(src)) {
- info = blurTextureCache->takeBlurTextureInfo(src);
- } else {
- m_animatedBlur = false;
- m_hints = QGraphicsBlurEffect::QualityHint;
- m_singlePass = false;
-
- QGLFramebufferObjectFormat format;
- format.setInternalTextureFormat(GLenum(GL_RGBA));
- QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size() / 2, format, true);
-
- if (!fbo)
- return false;
-
- QPainter fboPainter(fbo);
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(fboPainter.paintEngine());
-
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // ensure GL_LINEAR filtering is used for scaling down to half the size
- fboPainter.setRenderHint(QPainter::SmoothPixmapTransform);
- fboPainter.setCompositionMode(QPainter::CompositionMode_Source);
- fboPainter.drawPixmap(qMaxCachedBlurLevel / 2, qMaxCachedBlurLevel / 2,
- targetRect.width() / 2 - qMaxCachedBlurLevel, targetRect.height() / 2 - qMaxCachedBlurLevel, src);
-
- GLuint textures[qNumCachedBlurTextures]; // blur textures
- glGenTextures(qNumCachedBlurTextures, textures);
- GLuint temp; // temp texture
- glGenTextures(1, &temp);
-
- initializeTexture(temp, fbo->width(), fbo->height());
- m_textureSize = fbo->size();
-
- int currentBlur = 0;
-
- QRect fboRect(0, 0, fbo->width(), fbo->height());
- GLuint sourceTexture = fbo->texture();
- for (int i = 0; i < qNumCachedBlurTextures; ++i) {
- int targetBlur = qCachedBlurLevels[i] / 2;
-
- int blurDelta = qRound(qSqrt(targetBlur * targetBlur - currentBlur * currentBlur));
- QByteArray source = generateGaussianShader(blurDelta);
- filter->setSource(source);
-
- currentBlur = targetBlur;
-
- // now we're going to be nasty and keep using the same FBO with different textures
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, temp, 0);
-
- m_horizontalBlur = true;
- filter->setOnPainter(&fboPainter);
- engine->drawTexture(fboRect, sourceTexture, fbo->size(), fboRect);
- filter->removeFromPainter(&fboPainter);
-
- sourceTexture = textures[i];
- initializeTexture(sourceTexture, fbo->width(), fbo->height());
-
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, textures[i], 0);
-
- m_horizontalBlur = false;
- filter->setOnPainter(&fboPainter);
- engine->drawTexture(fboRect, temp, fbo->size(), fboRect);
- filter->removeFromPainter(&fboPainter);
- }
-
- glDeleteTextures(1, &temp);
+ uint mod = x % multiplier;
+ if (mod == 0)
+ return x;
+ return x + multiplier - mod;
+}
- // reattach the original FBO texture
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, fbo->texture(), 0);
+void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
+ quint32 *dest, int dstStride);
- fboPainter.end();
+bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
+{
+ if (radius() < 1) {
+ painter->drawPixmap(pos, src);
+ return true;
+ }
- qgl_fbo_pool()->release(fbo);
+ qreal actualRadius = radius();
- info = new QGLBlurTextureInfo(fboRect.size(), textures);
- }
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- if (!m_haveCached || !m_animatedBlur) {
- m_haveCached = true;
- m_animatedBlur = true;
- m_hints = QGraphicsBlurEffect::AnimationHint;
- filter->setSource(qt_gl_interpolate_filter);
- }
+ QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
+ QGLBlurTextureInfo *info = 0;
+ int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement);
+ QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- filter->setOnPainter(painter);
+ // pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times
+ targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
+ targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
- qreal logRadius = qLn(radius());
+ QSize textureSize;
- int t;
- for (t = -1; t < qNumCachedBlurTextures - 2; ++t) {
- if (logRadius < qLogBlurLevel(t+1))
- break;
- }
+ info = blurTextureCache->takeBlurTextureInfo(src);
+ if (!info || info->radius() < actualRadius) {
+ QSize paddedSize = targetRect.size() / 2;
- qreal logBase = t >= 0 ? qLogBlurLevel(t) : 0;
- m_t = qBound(qreal(0), (logRadius - logBase) / (qLogBlurLevel(t+1) - logBase), qreal(1));
+ QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied);
+ padded.fill(0);
- m_textureSize = info->size();
+ if (info) {
+ int oldPadding = qRound(info->radius());
- glActiveTexture(GL_TEXTURE0 + 3);
- if (t >= 0) {
- glBindTexture(GL_TEXTURE_2D, info->textureId(t));
- m_targetSize = info->size();
+ QPainter p(&padded);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage());
+ p.end();
} else {
- QGLTexture *texture =
- ctx->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption
- | QGLContext::CanFlipNativePixmapBindOption);
- m_targetSize = src.size();
- if (!(texture->options & QGLContext::InvertedYBindOption))
- m_targetSize.setHeight(-m_targetSize.height());
+ // TODO: combine byteswapping and memrotating into one by declaring
+ // custom GL_RGBA pixel type and qt_colorConvert template for it
+ QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ // byte-swap and memrotates in one go
+ qt_memrotate90_gl(reinterpret_cast<const quint32*>(prepadded.bits()),
+ prepadded.width(), prepadded.height(), prepadded.bytesPerLine(),
+ reinterpret_cast<quint32*>(padded.scanLine(padding / 2)) + padding / 2,
+ padded.bytesPerLine());
}
- // restrict the target rect to the max of the radii we are interpolating between
- int radiusDelta = qMaxCachedBlurLevel - qCachedBlurLevels[t+1];
- targetRect = targetRect.translated(pos.toPoint()).adjusted(radiusDelta, radiusDelta, -radiusDelta, -radiusDelta);
-
- radiusDelta /= 2;
- QRect sourceRect = QRect(QPoint(), m_textureSize).adjusted(radiusDelta, radiusDelta, -radiusDelta, -radiusDelta);
-
- engine->drawTexture(targetRect, info->textureId(t+1), m_textureSize, sourceRect);
-
- glActiveTexture(GL_TEXTURE0 + 3);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- filter->removeFromPainter(painter);
- blurTextureCache->insertBlurTextureInfo(src, info);
-
- return true;
- }
+ delete info;
+ info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding);
- if (blurTextureCache->hasBlurTextureInfo(src))
- blurTextureCache->clearBlurTextureInfo(src);
-
- int actualRadius = qRound(radius());
- int filterRadius = actualRadius;
- int fastRadii[] = { 1, 2, 3, 5, 8, 15, 25 };
- if (!(m_hints & QGraphicsBlurEffect::QualityHint)) {
- uint i = 0;
- for (; i < (sizeof(fastRadii)/sizeof(*fastRadii))-1; ++i) {
- if (fastRadii[i+1] > filterRadius)
- break;
- }
- filterRadius = fastRadii[i];
+ textureSize = paddedSize;
+ } else {
+ textureSize = QSize(info->paddedImage().height(), info->paddedImage().width());
}
- m_singlePass = filterRadius <= 3;
-
- if (!m_haveCached || m_animatedBlur || filterRadius != m_cachedRadius) {
- // Only regenerate the shader from source if parameters have changed.
- m_haveCached = true;
- m_animatedBlur = false;
- m_cachedRadius = filterRadius;
- QByteArray source = generateGaussianShader(filterRadius, m_singlePass);
- filter->setSource(source);
+ actualRadius *= qreal(0.5);
+ int level = 1;
+ for (; level < qMaxBlurHalfScaleLevel; ++level) {
+ if (actualRadius <= 16)
+ break;
+ actualRadius *= qreal(0.5);
}
- QRect targetRect = QRectF(src.rect()).translated(pos).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect();
+ const int s = (1 << level);
- if (m_singlePass) {
- // prepare for updateUniforms
- m_textureSize = src.size();
+ int prepadding = qRound(info->radius());
+ padding = qMin(prepadding, qCeil(actualRadius) << level);
+ targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
- // ensure GL_LINEAR filtering is used
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- filter->setOnPainter(painter);
- QBrush pixmapBrush = src;
- pixmapBrush.setTransform(QTransform::fromTranslate(pos.x(), pos.y()));
- painter->fillRect(targetRect, pixmapBrush);
- filter->removeFromPainter(painter);
- } else {
- QGLFramebufferObjectFormat format;
- format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB));
- QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format);
+ targetRect.setWidth(targetRect.width() & ~(s-1));
+ targetRect.setHeight(targetRect.height() & ~(s-1));
- if (!fbo)
- return false;
+ int paddingDelta = (prepadding - padding) >> level;
- // prepare for updateUniforms
- m_textureSize = src.size();
+ QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level);
+ QImage sourceImage = info->paddedImage(level-1);
- // horizontal pass, to pixmap
- m_horizontalBlur = true;
+ QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied);
+ qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta,
+ 0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine());
- QPainter fboPainter(fbo);
+ GLuint texture = info->texture();
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
+ qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1);
- // ensure GL_LINEAR filtering is used
- fboPainter.setRenderHint(QPainter::SmoothPixmapTransform);
- fboPainter.setCompositionMode(QPainter::CompositionMode_Source);
- filter->setOnPainter(&fboPainter);
- QBrush pixmapBrush = src;
- pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius));
- fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush);
- filter->removeFromPainter(&fboPainter);
- fboPainter.end();
+ // subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data
+ QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1);
+ QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height()));
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA,
+ GL_UNSIGNED_BYTE, const_cast<const QImage &>(subImage).bits());
- // vertical pass, to painter
- m_horizontalBlur = false;
- m_textureSize = fbo->size();
+ QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
+ painter->setRenderHint(QPainter::SmoothPixmapTransform);
- painter->save();
- // ensure GL_LINEAR filtering is used
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- filter->setOnPainter(painter);
- engine->drawTexture(targetRect, fbo->texture(), fbo->size(), QRect(QPoint(), targetRect.size()).translated(0, fbo->height() - targetRect.height()));
- filter->removeFromPainter(painter);
- painter->restore();
+ // texture is flipped on the y-axis
+ targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height());
+ engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect);
- qgl_fbo_pool()->release(fbo);
- }
+ blurTextureCache->insertBlurTextureInfo(src, info);
return true;
}
-void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program)
-{
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if (m_animatedBlur) {
- program->setUniformValue("interpolateTarget", 3);
- program->setUniformValue("interpolationValue", GLfloat(m_t));
-
- if (m_textureSize == m_targetSize) {
- program->setUniformValue("interpolateMapping", 0.0f, 0.0f, 1.0f, 1.0f);
- } else {
- float offsetX = (-qMaxCachedBlurLevel - 0.5) / qreal(m_targetSize.width());
- float offsetY = (-qMaxCachedBlurLevel - 0.5) / qreal(m_targetSize.height());
-
- if (m_targetSize.height() < 0)
- offsetY = 1 + offsetY;
-
- float scaleX = 2.0f * qreal(m_textureSize.width()) / qreal(m_targetSize.width());
- float scaleY = 2.0f * qreal(m_textureSize.height()) / qreal(m_targetSize.height());
-
- program->setUniformValue("interpolateMapping", offsetX, offsetY, scaleX, scaleY);
- }
-
- return;
- }
+static const char *qt_gl_drop_shadow_filter =
+ "uniform lowp vec4 shadowColor;"
+ "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
+ "{"
+ " return shadowColor * texture2D(src, srcCoords.yx).a;"
+ "}";
- if (m_hints & QGraphicsBlurEffect::QualityHint) {
- if (m_singlePass)
- program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height());
- else if (m_horizontalBlur)
- program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0);
- else
- program->setUniformValue("delta", 0.0, 1.0 / m_textureSize.height());
- } else {
- qreal blur = radius() / qreal(m_cachedRadius);
-
- if (m_singlePass)
- program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height());
- else if (m_horizontalBlur)
- program->setUniformValue("delta", blur / m_textureSize.width(), 0.0);
- else
- program->setUniformValue("delta", 0.0, blur / m_textureSize.height());
- }
-}
-static inline qreal gaussian(qreal dx, qreal sigma)
+QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter()
{
- return exp(-dx * dx / (2 * sigma * sigma)) / (Q_2PI * sigma * sigma);
+ setSource(qt_gl_drop_shadow_filter);
}
-QByteArray QGLPixmapBlurFilter::generateGaussianShader(int radius, bool singlePass, bool dropShadow)
+bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
- Q_ASSERT(radius >= 1);
-
- radius = qMin(127, radius);
-
- static QCache<uint, QByteArray> shaderSourceCache;
- uint key = radius | (int(singlePass) << 7) | (int(dropShadow) << 8);
- QByteArray *cached = shaderSourceCache.object(key);
- if (cached)
- return *cached;
-
- QByteArray source;
- source.reserve(1000);
- source.append(qt_gl_texture_sampling_helper);
-
- source.append("uniform highp vec2 delta;\n");
- if (dropShadow)
- source.append("uniform mediump vec4 shadowColor;\n");
- source.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");
-
- QVector<qreal> sampleOffsets;
- QVector<qreal> weights;
-
- QVector<qreal> gaussianComponents;
-
- qreal sigma = radius / 1.65;
-
- qreal sum = 0;
- for (int i = -radius; i < radius; ++i) {
- float value = gaussian(i, sigma);
- gaussianComponents << value;
- sum += value;
- }
-
- // normalize
- for (int i = 0; i < gaussianComponents.size(); ++i)
- gaussianComponents[i] /= sum;
-
- for (int i = 0; i < gaussianComponents.size() - 1; i += 2) {
- qreal weight = gaussianComponents.at(i) + gaussianComponents.at(i + 1);
- qreal offset = i - radius + gaussianComponents.at(i + 1) / weight;
-
- sampleOffsets << offset;
- weights << weight;
- }
-
- int limit = sampleOffsets.size();
- if (singlePass)
- limit *= limit;
-
- QByteArray baseCoordinate = "srcCoords";
-
- for (int i = 0; i < limit; ++i) {
- QByteArray coordinate = baseCoordinate;
-
- qreal weight;
- if (singlePass) {
- const int xIndex = i % sampleOffsets.size();
- const int yIndex = i / sampleOffsets.size();
-
- const qreal deltaX = sampleOffsets.at(xIndex);
- const qreal deltaY = sampleOffsets.at(yIndex);
- weight = weights.at(xIndex) * weights.at(yIndex);
-
- if (!qFuzzyCompare(deltaX, deltaY)) {
- coordinate.append(" + vec2(delta.x * float(");
- coordinate.append(QByteArray::number(deltaX));
- coordinate.append("), delta.y * float(");
- coordinate.append(QByteArray::number(deltaY));
- coordinate.append("))");
- } else if (!qFuzzyIsNull(deltaX)) {
- coordinate.append(" + delta * float(");
- coordinate.append(QByteArray::number(deltaX));
- coordinate.append(")");
- }
- } else {
- const qreal delta = sampleOffsets.at(i);
- weight = weights.at(i);
- if (!qFuzzyIsNull(delta)) {
- coordinate.append(" + delta * float(");
- coordinate.append(QByteArray::number(delta));
- coordinate.append(")");
- }
- }
-
- if (i == 0) {
- if (dropShadow)
- source.append(" mediump float sample = ");
- else
- source.append(" mediump vec4 sample = ");
- } else {
- if (dropShadow)
- source.append(" sample += ");
- else
- source.append(" sample += ");
- }
+ QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);
- source.append("texture2D(src, ");
- source.append(coordinate);
- source.append(")");
+ qreal r = blurRadius();
+ QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r);
+ QRect targetRect = targetRectUnaligned.toAlignedRect();
- if (dropShadow)
- source.append(".a");
+ // ensure even dimensions (going to divide by two)
+ targetRect.setWidth((targetRect.width() + 1) & ~1);
+ targetRect.setHeight((targetRect.height() + 1) & ~1);
- if (!qFuzzyCompare(weight, qreal(1))) {
- source.append(" * float(");
- source.append(QByteArray::number(weight));
- source.append(");\n");
- } else {
- source.append(";\n");
- }
- }
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
+ QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
- source.append(" return ");
- if (dropShadow)
- source.append("shadowColor * ");
- source.append("sample;\n");
- source.append("}\n");
+ QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src);
+ if (!info || info->radius() != r) {
+ QImage half = qt_halfScaled(src.toImage().alphaChannel());
- cached = new QByteArray(source);
- shaderSourceCache.insert(key, cached);
+ qreal rx = r + targetRect.left() - targetRectUnaligned.left();
+ qreal ry = r + targetRect.top() - targetRectUnaligned.top();
- return source;
-}
+ QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8);
+ image.setColorTable(half.colorTable());
+ image.fill(0);
+ int dx = qRound(rx * qreal(0.5));
+ int dy = qRound(ry * qreal(0.5));
+ qt_rectcopy(image.bits(), half.bits(), dx, dy,
+ half.width(), half.height(),
+ image.bytesPerLine(), half.bytesPerLine());
-QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter(QGraphicsBlurEffect::BlurHints hints)
- : m_haveCached(false)
- , m_cachedRadius(0)
- , m_hints(hints)
-{
-}
+ qt_blurImage(image, r * qreal(0.5), false, 1);
-bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
-{
- QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);
+ GLuint texture = generateBlurTexture(image.size(), GL_ALPHA);
- int actualRadius = qRound(blurRadius());
- int filterRadius = actualRadius;
- m_singlePass = filterRadius <= 3;
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_ALPHA,
+ GL_UNSIGNED_BYTE, image.bits());
- if (!m_haveCached || filterRadius != m_cachedRadius) {
- // Only regenerate the shader from source if parameters have changed.
- m_haveCached = true;
- m_cachedRadius = filterRadius;
- QByteArray source = QGLPixmapBlurFilter::generateGaussianShader(filterRadius, m_singlePass, true);
- filter->setSource(source);
+ info = new QGLBlurTextureInfo(image, texture, r);
}
- QRect targetRect = QRectF(src.rect()).translated(pos + offset()).adjusted(-actualRadius, -actualRadius, actualRadius, actualRadius).toAlignedRect();
-
- if (m_singlePass) {
- // prepare for updateUniforms
- m_textureSize = src.size();
-
- painter->save();
- // ensure GL_LINEAR filtering is used
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- filter->setOnPainter(painter);
- QBrush pixmapBrush = src;
- pixmapBrush.setTransform(QTransform::fromTranslate(pos.x() + offset().x(), pos.y() + offset().y()));
- painter->fillRect(targetRect, pixmapBrush);
- filter->removeFromPainter(painter);
- painter->restore();
- } else {
- QGLFramebufferObjectFormat format;
- format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB));
- QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(targetRect.size(), format);
-
- if (!fbo)
- return false;
-
- // prepare for updateUniforms
- m_textureSize = src.size();
-
- // horizontal pass, to pixmap
- m_horizontalBlur = true;
-
- QPainter fboPainter(fbo);
+ GLuint texture = info->texture();
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // ensure GL_LINEAR filtering is used
- fboPainter.setRenderHint(QPainter::SmoothPixmapTransform);
- fboPainter.setCompositionMode(QPainter::CompositionMode_Source);
- filter->setOnPainter(&fboPainter);
- QBrush pixmapBrush = src;
- pixmapBrush.setTransform(QTransform::fromTranslate(actualRadius, actualRadius));
- fboPainter.fillRect(QRect(0, 0, targetRect.width(), targetRect.height()), pixmapBrush);
- filter->removeFromPainter(&fboPainter);
- fboPainter.end();
-
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
+ filter->setOnPainter(painter);
- // vertical pass, to painter
- m_horizontalBlur = false;
- m_textureSize = fbo->size();
+ QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
+ painter->setRenderHint(QPainter::SmoothPixmapTransform);
- painter->save();
- // ensure GL_LINEAR filtering is used
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- filter->setOnPainter(painter);
- engine->drawTexture(targetRect, fbo->texture(), fbo->size(), QRectF(0, fbo->height() - targetRect.height(), targetRect.width(), targetRect.height()));
- filter->removeFromPainter(painter);
- painter->restore();
+ engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect());
- qgl_fbo_pool()->release(fbo);
- }
+ filter->removeFromPainter(painter);
// Now draw the actual pixmap over the top.
painter->drawPixmap(pos, src, srcRect);
+ blurTextureCache->insertBlurTextureInfo(src, info);
+
return true;
}
void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program)
{
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
QColor col = color();
- if (m_horizontalBlur && !m_singlePass) {
- program->setUniformValue("shadowColor", 1.0f, 1.0f, 1.0f, 1.0f);
- } else {
- qreal alpha = col.alphaF();
- program->setUniformValue("shadowColor", col.redF() * alpha,
- col.greenF() * alpha,
- col.blueF() * alpha,
- alpha);
- }
-
- if (m_hints & QGraphicsBlurEffect::QualityHint) {
- if (m_singlePass)
- program->setUniformValue("delta", 1.0 / m_textureSize.width(), 1.0 / m_textureSize.height());
- else if (m_horizontalBlur)
- program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0);
- else
- program->setUniformValue("delta", 0.0, 1.0 / m_textureSize.height());
- } else {
- qreal blur = blurRadius() / qreal(m_cachedRadius);
-
- if (m_singlePass)
- program->setUniformValue("delta", blur / m_textureSize.width(), blur / m_textureSize.height());
- else if (m_horizontalBlur)
- program->setUniformValue("delta", blur / m_textureSize.width(), 0.0);
- else
- program->setUniformValue("delta", 0.0, blur / m_textureSize.height());
- }
+ qreal alpha = col.alphaF();
+ program->setUniformValue("shadowColor", col.redF() * alpha,
+ col.greenF() * alpha,
+ col.blueF() * alpha,
+ alpha);
}
QT_END_NAMESPACE
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index b4191dc..f9737a56 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -2275,6 +2275,42 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value
\overload
Sets the uniform variable at \a location in the current context
+ to a 2x2 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+ \since 4.6.2
+*/
+void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
+{
+ Q_D(QGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable at \a location in the current context
+ to a 3x3 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+ \since 4.6.2
+*/
+void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
+{
+ Q_D(QGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable at \a location in the current context
to a 4x4 matrix \a value. The matrix elements must be specified
in column-major order.
@@ -2288,6 +2324,37 @@ void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 2x2 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+ \since 4.6.2
+*/
+void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2])
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 3x3 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+ \since 4.6.2
+*/
+void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3])
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
/*!
\overload
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index deeaee2..4eb80dd 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -216,6 +216,8 @@ public:
void setUniformValue(int location, const QMatrix4x2& value);
void setUniformValue(int location, const QMatrix4x3& value);
void setUniformValue(int location, const QMatrix4x4& value);
+ void setUniformValue(int location, const GLfloat value[2][2]);
+ void setUniformValue(int location, const GLfloat value[3][3]);
void setUniformValue(int location, const GLfloat value[4][4]);
void setUniformValue(int location, const QTransform& value);
@@ -242,6 +244,8 @@ public:
void setUniformValue(const char *name, const QMatrix4x2& value);
void setUniformValue(const char *name, const QMatrix4x3& value);
void setUniformValue(const char *name, const QMatrix4x4& value);
+ void setUniformValue(const char *name, const GLfloat value[2][2]);
+ void setUniformValue(const char *name, const GLfloat value[3][3]);
void setUniformValue(const char *name, const GLfloat value[4][4]);
void setUniformValue(const char *name, const QTransform& value);
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 8ab17a0..8dae02a 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -110,11 +110,7 @@ static bool DEBUG_TEMP_FLAG;
static inline void qt_glColor4ubv(unsigned char *col)
{
-#ifdef QT_OPENGL_ES
- glColor4f(col[0]/255.0, col[1]/255.0, col[2]/255.0, col[3]/255.0);
-#else
- glColor4ubv(col);
-#endif
+ glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f);
}
struct QT_PointF {
@@ -4526,6 +4522,12 @@ typedef QHash<QFontEngine*, QGLGlyphHash*> QGLFontGlyphHash;
typedef QHash<quint64, QGLFontTexture*> QGLFontTexHash;
typedef QHash<const QGLContext*, QGLFontGlyphHash*> QGLContextHash;
+static inline void qt_delete_glyph_hash(QGLGlyphHash *hash)
+{
+ qDeleteAll(*hash);
+ delete hash;
+}
+
class QGLGlyphCache : public QObject
{
Q_OBJECT
@@ -4566,7 +4568,7 @@ void QGLGlyphCache::fontEngineDestroyed(QObject *o)
if (font_cache->find(fe) != font_cache->end()) {
ctx = keys.at(i);
QGLGlyphHash *cache = font_cache->take(fe);
- delete cache;
+ qt_delete_glyph_hash(cache);
break;
}
}
@@ -4603,7 +4605,7 @@ void QGLGlyphCache::cleanupContext(const QGLContext *ctx)
QList<QFontEngine *> keys = font_cache->keys();
for (int i=0; i < keys.size(); ++i) {
QFontEngine *fe = keys.at(i);
- delete font_cache->take(fe);
+ qt_delete_glyph_hash(font_cache->take(fe));
quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe);
QGLFontTexture *font_tex = qt_font_textures.take(font_key);
if (font_tex) {
@@ -4644,7 +4646,9 @@ void QGLGlyphCache::cleanCache()
QList<const QGLContext *> keys = qt_context_cache.keys();
for (int i=0; i < keys.size(); ++i) {
QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i));
- qDeleteAll(*font_cache);
+ QGLFontGlyphHash::Iterator it = font_cache->begin();
+ for (; it != font_cache->end(); ++it)
+ qt_delete_glyph_hash(it.value());
font_cache->clear();
}
qDeleteAll(qt_context_cache);
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index fb55097..92c990b 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -53,6 +53,8 @@
#include <private/qpaintengineex_opengl2_p.h>
#include <qdesktopwidget.h>
+#include <qfile.h>
+#include <qimagereader.h>
QT_BEGIN_NAMESPACE
@@ -321,25 +323,36 @@ void QGLPixmapData::ensureCreated() const
QGLShareContextScope ctx(qt_gl_share_widget()->context());
m_ctx = ctx;
- const GLenum format = qt_gl_preferredTextureFormat();
+ 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;
if (!m_texture.id) {
glGenTextures(1, &m_texture.id);
glBindTexture(target, m_texture.id);
- GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB;
- glTexImage2D(target, 0, format, w, h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
if (!m_source.isNull()) {
- const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format);
-
- glBindTexture(target, m_texture.id);
- glTexSubImage2D(target, 0, 0, 0, w, h, format,
- GL_UNSIGNED_BYTE, tx.bits());
+ if (external_format == GL_RGB) {
+ const QImage tx = m_source.convertToFormat(QImage::Format_RGB888);
+
+ glBindTexture(target, m_texture.id);
+ glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
+ GL_UNSIGNED_BYTE, tx.bits());
+ } else {
+ const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format);
+
+ glBindTexture(target, m_texture.id);
+ glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
+ GL_UNSIGNED_BYTE, tx.bits());
+ }
if (useFramebufferObjects())
m_source = QImage();
@@ -385,6 +398,63 @@ void QGLPixmapData::fromImage(const QImage &image,
}
}
+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))
+ 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;
+ }
+ return false;
+ }
+ fromImage(QImageReader(&file, format).read(), flags);
+ 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 = QImage();
+ m_dirty = isValid();
+ return true;
+ }
+ }
+ return QPixmapData::fromData(buffer, len, format, flags);
+}
+
bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
{
Q_UNUSED(dx);
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 8a13e03..007c52a 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -106,6 +106,10 @@ public:
// Re-implemented from QPixmapData:
void resize(int width, int height);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ bool fromFile(const QString &filename, const char *format,
+ Qt::ImageConversionFlags flags);
+ bool fromData(const uchar *buffer, uint len, const char *format,
+ Qt::ImageConversionFlags flags);
void copy(const QPixmapData *data, const QRect &rect);
bool scroll(int dx, int dy, const QRect &rect);
void fill(const QColor &color);
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index e353f5d..7194f9d 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -493,7 +493,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
}
#endif
d_ptr->paintedRegion = QRegion();
-
context()->swapBuffers();
} else {
glFlush();
@@ -688,11 +687,13 @@ void QGLWindowSurface::updateGeometry() {
d_ptr->size = rect.size();
if (d_ptr->ctx) {
+#ifndef QT_OPENGL_ES_2
if (d_ptr->destructive_swap_buffers) {
glBindTexture(target, d_ptr->tex_id);
glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture(target, 0);
}
+#endif
return;
}
@@ -756,11 +757,7 @@ void QGLWindowSurface::updateGeometry() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
-#ifndef QT_OPENGL_ES
glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
-#else
- glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
-#endif
d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true;
return;
@@ -774,6 +771,7 @@ void QGLWindowSurface::updateGeometry() {
ctx->makeCurrent();
+#ifndef QT_OPENGL_ES_2
if (d_ptr->destructive_swap_buffers) {
glGenTextures(1, &d_ptr->tex_id);
glBindTexture(target, d_ptr->tex_id);
@@ -783,6 +781,7 @@ void QGLWindowSurface::updateGeometry() {
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(target, 0);
}
+#endif
qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;;
d_ptr->ctx = ctx;
diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro
index bf224b4..c8c9917 100644
--- a/src/openvg/openvg.pro
+++ b/src/openvg/openvg.pro
@@ -16,11 +16,13 @@ HEADERS += \
qpaintengine_vg_p.h \
qpixmapdata_vg_p.h \
qpixmapfilter_vg_p.h \
- qvgcompositionhelper_p.h
+ qvgcompositionhelper_p.h \
+ qvgimagepool_p.h
SOURCES += \
qpaintengine_vg.cpp \
qpixmapdata_vg.cpp \
- qpixmapfilter_vg.cpp
+ qpixmapfilter_vg.cpp \
+ qvgimagepool.cpp
contains(QT_CONFIG, egl) {
HEADERS += \
@@ -34,6 +36,7 @@ contains(QT_CONFIG, egl) {
include(../qbase.pri)
unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui
+symbian:TARGET.UID3 = 0x2001E62F
!isEmpty(QMAKE_INCDIR_OPENVG): INCLUDEPATH += $$QMAKE_INCDIR_OPENVG
!isEmpty(QMAKE_LIBDIR_OPENVG): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENVG
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 6b829dd..04fee08 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -43,6 +43,7 @@
#include "qpixmapdata_vg_p.h"
#include "qpixmapfilter_vg_p.h"
#include "qvgcompositionhelper_p.h"
+#include "qvgimagepool_p.h"
#if !defined(QT_NO_EGL)
#include <QtGui/private/qegl_p.h>
#include "qwindowsurface_vgegl_p.h"
@@ -1018,7 +1019,7 @@ static VGImage toVGImage
const uchar *pixels = img.bits();
- VGImage vgImg = vgCreateImage
+ VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
vgImageSubData
(vgImg, pixels, img.bytesPerLine(), format, 0, 0,
@@ -1063,7 +1064,7 @@ static VGImage toVGImageSubRect
const uchar *pixels = img.bits() + bpp * sr.x() +
img.bytesPerLine() * sr.y();
- VGImage vgImg = vgCreateImage
+ VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
vgImageSubData
(vgImg, pixels, img.bytesPerLine(), format, 0, 0,
@@ -1084,7 +1085,7 @@ static VGImage toVGImageWithOpacity(const QImage & image, qreal opacity)
const uchar *pixels = img.bits();
- VGImage vgImg = vgCreateImage
+ VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
vgImageSubData
(vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
@@ -1106,7 +1107,7 @@ static VGImage toVGImageWithOpacitySubRect
const uchar *pixels = img.bits();
- VGImage vgImg = vgCreateImage
+ VGImage vgImg = QVGImagePool::instance()->createPermanentImage
(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
vgImageSubData
(vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
@@ -1194,6 +1195,12 @@ VGPaintType QVGPaintEnginePrivate::setBrush
if (pd->classId() == QPixmapData::OpenVGClass) {
QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
vgImg = vgpd->toVGImage();
+
+ // We don't want the pool to reclaim this image
+ // because we cannot predict when the paint object
+ // will stop using it. Replacing the image with
+ // new data will make the paint object invalid.
+ vgpd->detachImageFromPool();
} else {
vgImg = toVGImage(*(pd->buffer()));
deref = true;
@@ -1201,6 +1208,7 @@ VGPaintType QVGPaintEnginePrivate::setBrush
} else if (pd->classId() == QPixmapData::OpenVGClass) {
QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
vgImg = vgpd->toVGImage(opacity);
+ vgpd->detachImageFromPool();
} else {
vgImg = toVGImageWithOpacity(*(pd->buffer()), opacity);
deref = true;
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 19c90ed..358ec4d 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -43,6 +43,7 @@
#include "qpaintengine_vg_p.h"
#include <QtGui/private/qdrawhelper_p.h>
#include "qvg_p.h"
+#include "qvgimagepool_p.h"
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
#include <graphics/sgimage.h>
@@ -63,41 +64,68 @@ QVGPixmapData::QVGPixmapData(PixelType type)
vgImageOpacity = VG_INVALID_HANDLE;
cachedOpacity = 1.0f;
recreate = true;
+ inImagePool = false;
+ inLRU = false;
#if !defined(QT_NO_EGL)
context = 0;
+ qt_vg_register_pixmap(this);
#endif
setSerialNumber(++qt_vg_pixmap_serial);
}
QVGPixmapData::~QVGPixmapData()
{
+ destroyImageAndContext();
+#if !defined(QT_NO_EGL)
+ qt_vg_unregister_pixmap(this);
+#endif
+}
+
+void QVGPixmapData::destroyImages()
+{
+ if (inImagePool) {
+ QVGImagePool *pool = QVGImagePool::instance();
+ if (vgImage != VG_INVALID_HANDLE)
+ pool->releaseImage(this, vgImage);
+ if (vgImageOpacity != VG_INVALID_HANDLE)
+ pool->releaseImage(this, vgImageOpacity);
+ } else {
+ if (vgImage != VG_INVALID_HANDLE)
+ vgDestroyImage(vgImage);
+ if (vgImageOpacity != VG_INVALID_HANDLE)
+ vgDestroyImage(vgImageOpacity);
+ }
+ vgImage = VG_INVALID_HANDLE;
+ vgImageOpacity = VG_INVALID_HANDLE;
+ inImagePool = false;
+}
+
+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->isCurrent()) {
- vgDestroyImage(vgImage);
- if (vgImageOpacity != VG_INVALID_HANDLE)
- vgDestroyImage(vgImageOpacity);
+ destroyImages();
} else {
// We don't currently have a widget surface active, but we
// need a surface to make the context current. So use the
// shared pbuffer surface instead.
context->makeCurrent(qt_vg_shared_surface());
- vgDestroyImage(vgImage);
- if (vgImageOpacity != VG_INVALID_HANDLE)
- vgDestroyImage(vgImageOpacity);
+ destroyImages();
context->lazyDoneCurrent();
}
#else
- vgDestroyImage(vgImage);
- if (vgImageOpacity != VG_INVALID_HANDLE)
- vgDestroyImage(vgImageOpacity);
+ destroyImages();
#endif
}
#if !defined(QT_NO_EGL)
- if (context)
- qt_vg_destroy_context(context);
+ if (context) {
+ qt_vg_destroy_context(context, QInternal::Pixmap);
+ context = 0;
+ }
#endif
+ recreate = true;
}
QPixmapData *QVGPixmapData::createCompatiblePixmapData() const
@@ -217,25 +245,25 @@ VGImage QVGPixmapData::toVGImage()
#if !defined(QT_NO_EGL)
// Increase the reference count on the shared context.
if (!context)
- context = qt_vg_create_context(0);
+ context = qt_vg_create_context(0, QInternal::Pixmap);
#endif
- if (recreate && prevSize != QSize(w, h)) {
- if (vgImage != VG_INVALID_HANDLE) {
- vgDestroyImage(vgImage);
- vgImage = VG_INVALID_HANDLE;
- }
- if (vgImageOpacity != VG_INVALID_HANDLE) {
- vgDestroyImage(vgImageOpacity);
- vgImageOpacity = VG_INVALID_HANDLE;
- }
- } else if (recreate) {
+ if (recreate && prevSize != QSize(w, h))
+ destroyImages();
+ else if (recreate)
cachedOpacity = -1.0f; // Force opacity image to be refreshed later.
- }
if (vgImage == VG_INVALID_HANDLE) {
- vgImage = vgCreateImage
- (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
+ vgImage = QVGImagePool::instance()->createImageForPixmap
+ (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
+
+ // Bail out if we run out of GPU memory - try again next time.
+ if (vgImage == VG_INVALID_HANDLE)
+ return VG_INVALID_HANDLE;
+
+ inImagePool = true;
+ } else if (inImagePool) {
+ QVGImagePool::instance()->useImage(this);
}
if (!source.isNull() && recreate) {
@@ -264,8 +292,17 @@ VGImage QVGPixmapData::toVGImage(qreal opacity)
// Create an alternative image for the selected opacity.
if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) {
if (vgImageOpacity == VG_INVALID_HANDLE) {
- vgImageOpacity = vgCreateImage
- (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
+ if (inImagePool) {
+ vgImageOpacity = QVGImagePool::instance()->createImageForPixmap
+ (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
+ } else {
+ vgImageOpacity = vgCreateImage
+ (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
+ }
+
+ // Bail out if we run out of GPU memory - try again next time.
+ if (vgImageOpacity == VG_INVALID_HANDLE)
+ return VG_INVALID_HANDLE;
}
VGfloat matrix[20] = {
1.0f, 0.0f, 0.0f, 0.0f,
@@ -286,6 +323,33 @@ VGImage QVGPixmapData::toVGImage(qreal opacity)
#endif
}
+void QVGPixmapData::detachImageFromPool()
+{
+ if (inImagePool) {
+ QVGImagePool::instance()->detachImage(this);
+ inImagePool = false;
+ }
+}
+
+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())
+ return;
+
+ forceToImage();
+ destroyImageAndContext();
+}
+
+void QVGPixmapData::reclaimImages()
+{
+ if (!inImagePool)
+ return;
+ forceToImage();
+ destroyImages();
+}
+
extern int qt_defaultDpiX();
extern int qt_defaultDpiY();
@@ -376,16 +440,9 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
// when "0" used as argument then
// default display, context are used
if (!context)
- context = qt_vg_create_context(0);
+ context = qt_vg_create_context(0, QInternal::Pixmap);
- if (vgImage != VG_INVALID_HANDLE) {
- vgDestroyImage(vgImage);
- vgImage = VG_INVALID_HANDLE;
- }
- if (vgImageOpacity != VG_INVALID_HANDLE) {
- vgDestroyImage(vgImageOpacity);
- vgImageOpacity = VG_INVALID_HANDLE;
- }
+ destroyImages();
prevSize = QSize();
TInt err = 0;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index fe19f35..4ff95c1 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -55,8 +55,6 @@
#include <QtGui/private/qpixmap_raster_p.h>
#include <private/qvg_p.h>
-#if !defined(QT_NO_EGL)
-#endif
#if defined(Q_OS_SYMBIAN)
class RSGImage;
@@ -65,6 +63,16 @@ class RSGImage;
QT_BEGIN_NAMESPACE
class QEglContext;
+class QVGImagePool;
+
+#if !defined(QT_NO_EGL)
+class QVGPixmapData;
+class QVGSharedContext;
+
+void qt_vg_register_pixmap(QVGPixmapData *pd);
+void qt_vg_unregister_pixmap(QVGPixmapData *pd);
+void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
+#endif
class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData
{
@@ -94,6 +102,21 @@ public:
// Return the VGImage form for a specific opacity setting.
virtual VGImage toVGImage(qreal opacity);
+ // Detach this image from the image pool.
+ virtual void detachImageFromPool();
+
+ // Release the VG resources associated with this pixmap and copy
+ // the pixmap's contents out of the GPU back into main memory.
+ // The VG resource will be automatically recreated the next time
+ // toVGImage() is called. Does nothing if the pixmap cannot be
+ // hibernated for some reason (e.g. VGImage is shared with another
+ // process via a SgImage).
+ virtual void hibernate();
+
+ // Called when the QVGImagePool wants to reclaim this pixmap's
+ // VGImage objects to reuse storage.
+ virtual void reclaimImages();
+
QSize size() const { return QSize(w, h); }
#if defined(Q_OS_SYMBIAN)
@@ -108,6 +131,21 @@ protected:
void cleanup();
#endif
+private:
+ QVGPixmapData *nextLRU;
+ QVGPixmapData *prevLRU;
+ bool inLRU;
+ friend class QVGImagePool;
+
+#if !defined(QT_NO_EGL)
+ QVGPixmapData *next;
+ QVGPixmapData *prev;
+
+ friend void qt_vg_register_pixmap(QVGPixmapData *pd);
+ friend void qt_vg_unregister_pixmap(QVGPixmapData *pd);
+ friend void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
+#endif
+
protected:
QSize prevSize;
VGImage vgImage;
@@ -115,12 +153,16 @@ protected:
qreal cachedOpacity;
mutable QImage source;
mutable bool recreate;
+ bool inImagePool;
#if !defined(QT_NO_EGL)
mutable QEglContext *context;
#endif
void forceToImage();
QImage::Format sourceFormat() const;
+
+ void destroyImageAndContext();
+ void destroyImages();
};
QT_END_NAMESPACE
diff --git a/src/openvg/qpixmapfilter_vg.cpp b/src/openvg/qpixmapfilter_vg.cpp
index e17c728..aa526ed 100644
--- a/src/openvg/qpixmapfilter_vg.cpp
+++ b/src/openvg/qpixmapfilter_vg.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qpixmapfilter_vg_p.h"
+#include "qvgimagepool_p.h"
#include <QtCore/qvarlengtharray.h>
#include <QtGui/qpainter.h>
@@ -82,9 +83,9 @@ void QVGPixmapConvolutionFilter::draw
return;
QSize size = pd->size();
- VGImage dstImage = vgCreateImage
+ VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
(VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER);
+ VG_IMAGE_QUALITY_FASTER, pd);
if (dstImage == VG_INVALID_HANDLE)
return;
@@ -124,7 +125,7 @@ void QVGPixmapConvolutionFilter::draw
if(child != dstImage)
vgDestroyImage(child);
- vgDestroyImage(dstImage);
+ QVGImagePool::instance()->releaseImage(0, dstImage);
}
QVGPixmapColorizeFilter::QVGPixmapColorizeFilter()
@@ -155,9 +156,9 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const
return;
QSize size = pd->size();
- VGImage dstImage = vgCreateImage
+ VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
(VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER);
+ VG_IMAGE_QUALITY_FASTER, pd);
if (dstImage == VG_INVALID_HANDLE)
return;
@@ -217,7 +218,7 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const
if(child != dstImage)
vgDestroyImage(child);
- vgDestroyImage(dstImage);
+ QVGImagePool::instance()->releaseImage(0, dstImage);
}
QVGPixmapDropShadowFilter::QVGPixmapDropShadowFilter()
@@ -248,9 +249,9 @@ void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, con
return;
QSize size = pd->size();
- VGImage dstImage = vgCreateImage
+ VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
(VG_A_8, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER);
+ VG_IMAGE_QUALITY_FASTER, pd);
if (dstImage == VG_INVALID_HANDLE)
return;
@@ -282,7 +283,7 @@ void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, con
if(child != dstImage)
vgDestroyImage(child);
- vgDestroyImage(dstImage);
+ QVGImagePool::instance()->releaseImage(0, dstImage);
// Now draw the actual pixmap over the top.
painter->drawPixmap(dest, src, srect);
@@ -316,9 +317,9 @@ void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPi
return;
QSize size = pd->size();
- VGImage dstImage = vgCreateImage
+ VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
(VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER);
+ VG_IMAGE_QUALITY_FASTER, pd);
if (dstImage == VG_INVALID_HANDLE)
return;
@@ -347,7 +348,7 @@ void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPi
if(child != dstImage)
vgDestroyImage(child);
- vgDestroyImage(dstImage);
+ QVGImagePool::instance()->releaseImage(0, dstImage);
}
#endif
diff --git a/src/openvg/qvg_p.h b/src/openvg/qvg_p.h
index 04e2bab..3577013 100644
--- a/src/openvg/qvg_p.h
+++ b/src/openvg/qvg_p.h
@@ -71,11 +71,17 @@ class QEglContext;
// Create an EGL context, but don't bind it to a surface. If single-context
// mode is enabled, this will return the previously-created context.
-Q_OPENVG_EXPORT QEglContext *qt_vg_create_context(QPaintDevice *device);
+// "devType" indicates the type of device using the context, usually
+// QInternal::Widget or QInternal::Pixmap.
+Q_OPENVG_EXPORT QEglContext *qt_vg_create_context
+ (QPaintDevice *device, int devType);
// Destroy an EGL context that was created by qt_vg_create_context().
// If single-context mode is enabled, this will decrease the reference count.
-Q_OPENVG_EXPORT void qt_vg_destroy_context(QEglContext *context);
+// "devType" indicates the type of device destroying the context, usually
+// QInternal::Widget or QInternal::Pixmap.
+Q_OPENVG_EXPORT void qt_vg_destroy_context
+ (QEglContext *context, int devType);
// Return the shared pbuffer surface that can be made current to
// destroy VGImage objects when there is no other surface available.
diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp
new file mode 100644
index 0000000..93e6e03
--- /dev/null
+++ b/src/openvg/qvgimagepool.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 "qvgimagepool_p.h"
+#include "qpixmapdata_vg_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QVGImagePool *qt_vg_image_pool = 0;
+
+class QVGImagePoolPrivate
+{
+public:
+ QVGImagePoolPrivate() : lruFirst(0), lruLast(0) {}
+
+ QVGPixmapData *lruFirst;
+ QVGPixmapData *lruLast;
+};
+
+QVGImagePool::QVGImagePool()
+ : d_ptr(new QVGImagePoolPrivate())
+{
+}
+
+QVGImagePool::~QVGImagePool()
+{
+}
+
+QVGImagePool *QVGImagePool::instance()
+{
+ if (!qt_vg_image_pool)
+ qt_vg_image_pool = new QVGImagePool();
+ return qt_vg_image_pool;
+}
+
+void QVGImagePool::setImagePool(QVGImagePool *pool)
+{
+ if (qt_vg_image_pool != pool)
+ delete qt_vg_image_pool;
+ qt_vg_image_pool = pool;
+}
+
+VGImage QVGImagePool::createTemporaryImage(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality,
+ QVGPixmapData *keepData)
+{
+ VGImage image;
+ do {
+ image = vgCreateImage(format, width, height, allowedQuality);
+ if (image != VG_INVALID_HANDLE)
+ return image;
+ } while (reclaimSpace(format, width, height, keepData));
+ qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d temporary image",
+ width, height);
+ return VG_INVALID_HANDLE;
+}
+
+VGImage QVGImagePool::createImageForPixmap(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality,
+ QVGPixmapData *data)
+{
+ VGImage image;
+ do {
+ image = vgCreateImage(format, width, height, allowedQuality);
+ if (image != VG_INVALID_HANDLE) {
+ if (data)
+ moveToHeadOfLRU(data);
+ return image;
+ }
+ } while (reclaimSpace(format, width, height, data));
+ qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ width, height);
+ return VG_INVALID_HANDLE;
+}
+
+VGImage QVGImagePool::createPermanentImage(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality)
+{
+ VGImage image;
+ do {
+ image = vgCreateImage(format, width, height, allowedQuality);
+ if (image != VG_INVALID_HANDLE)
+ return image;
+ } while (reclaimSpace(format, width, height, 0));
+ qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d image",
+ width, height);
+ return VG_INVALID_HANDLE;
+}
+
+void QVGImagePool::releaseImage(QVGPixmapData *data, VGImage image)
+{
+ // Very simple strategy at the moment: just destroy the image.
+ if (data)
+ removeFromLRU(data);
+ vgDestroyImage(image);
+}
+
+void QVGImagePool::useImage(QVGPixmapData *data)
+{
+ moveToHeadOfLRU(data);
+}
+
+void QVGImagePool::detachImage(QVGPixmapData *data)
+{
+ removeFromLRU(data);
+}
+
+bool QVGImagePool::reclaimSpace(VGImageFormat format,
+ VGint width, VGint height,
+ QVGPixmapData *data)
+{
+ Q_UNUSED(format); // For future use in picking the best image to eject.
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+
+ if (data)
+ moveToHeadOfLRU(data);
+
+ QVGPixmapData *lrudata = pixmapLRU();
+ if (lrudata && lrudata != data) {
+ lrudata->reclaimImages();
+ return true;
+ }
+
+ return false;
+}
+
+void QVGImagePool::hibernate()
+{
+ // Nothing to do here at the moment since the pool does not
+ // retain VGImage's after they have been released.
+}
+
+void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
+{
+ Q_D(QVGImagePool);
+ 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 QVGImagePool::removeFromLRU(QVGPixmapData *data)
+{
+ Q_D(QVGImagePool);
+ 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;
+}
+
+QVGPixmapData *QVGImagePool::pixmapLRU()
+{
+ Q_D(QVGImagePool);
+ return d->lruLast;
+}
+
+QT_END_NAMESPACE
diff --git a/src/openvg/qvgimagepool_p.h b/src/openvg/qvgimagepool_p.h
new file mode 100644
index 0000000..66a4998
--- /dev/null
+++ b/src/openvg/qvgimagepool_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 QVGIMAGEPOOL_P_H
+#define QVGIMAGEPOOL_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 "qvg.h"
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVGPixmapData;
+class QVGImagePoolPrivate;
+
+class Q_OPENVG_EXPORT QVGImagePool
+{
+public:
+ QVGImagePool();
+ virtual ~QVGImagePool();
+
+ static QVGImagePool *instance();
+
+ // This function can be used from system-specific graphics system
+ // plugins to alter the image allocation strategy.
+ static void setImagePool(QVGImagePool *pool);
+
+ // Create a new VGImage from the pool with the specified parameters
+ // that is not associated with a pixmap. The VGImage is returned to
+ // the pool when releaseImage() is called.
+ //
+ // This function will call reclaimSpace() when vgCreateImage() fails.
+ //
+ // This function is typically called when allocating temporary
+ // VGImage's for pixmap filters. The "keepData" object will not
+ // be reclaimed if reclaimSpace() needs to be called.
+ virtual VGImage createTemporaryImage(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality,
+ QVGPixmapData *keepData = 0);
+
+ // Create a new VGImage with the specified parameters and associate
+ // it with "data". The QVGPixmapData will be notified when the
+ // VGImage needs to be reclaimed by the pool.
+ //
+ // This function will call reclaimSpace() when vgCreateImage() fails.
+ virtual VGImage createImageForPixmap(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality,
+ QVGPixmapData *data);
+
+ // Create a permanent VGImage with the specified parameters.
+ // If there is insufficient space for the vgCreateImage call,
+ // then this function will call reclaimSpace() and try again.
+ //
+ // The caller is responsible for calling vgDestroyImage()
+ // when it no longer needs the VGImage, as the image is not
+ // recorded in the image pool.
+ //
+ // This function is typically used for pattern brushes where
+ // the OpenVG engine is responsible for managing the lifetime
+ // of the VGImage, destroying it automatically when the brush
+ // is no longer in use.
+ virtual VGImage createPermanentImage(VGImageFormat format,
+ VGint width, VGint height,
+ VGbitfield allowedQuality);
+
+ // Release a VGImage that is no longer required.
+ virtual void releaseImage(QVGPixmapData *data, VGImage image);
+
+ // Notify the pool that a QVGPixmapData object is using
+ // an image again. This allows the pool to move the image
+ // within a least-recently-used list of QVGPixmapData objects.
+ virtual void useImage(QVGPixmapData *data);
+
+ // Notify the pool that the VGImage's associated with a
+ // QVGPixmapData are being detached from the pool. The caller
+ // will become responsible for calling vgDestroyImage().
+ virtual void detachImage(QVGPixmapData *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.
+ virtual bool reclaimSpace(VGImageFormat format,
+ VGint width, VGint height,
+ QVGPixmapData *data);
+
+ // Hibernate the image pool because the context is about to be
+ // destroyed. All VGImage's left in the pool should be released.
+ virtual void hibernate();
+
+protected:
+ // Helper functions for managing the LRU list of QVGPixmapData objects.
+ void moveToHeadOfLRU(QVGPixmapData *data);
+ void removeFromLRU(QVGPixmapData *data);
+ QVGPixmapData *pixmapLRU();
+
+private:
+ QScopedPointer<QVGImagePoolPrivate> d_ptr;
+
+ Q_DECLARE_PRIVATE(QVGImagePool)
+ Q_DISABLE_COPY(QVGImagePool)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp
index 62871cf..bda6096 100644
--- a/src/openvg/qwindowsurface_vgegl.cpp
+++ b/src/openvg/qwindowsurface_vgegl.cpp
@@ -42,6 +42,7 @@
#include "qwindowsurface_vgegl_p.h"
#include "qpaintengine_vg_p.h"
#include "qpixmapdata_vg_p.h"
+#include "qvgimagepool_p.h"
#include "qvg_p.h"
#if !defined(QT_NO_EGL)
@@ -111,15 +112,19 @@ public:
QEglContext *context;
int refCount;
+ int widgetRefCount;
QVGPaintEngine *engine;
EGLSurface surface;
+ QVGPixmapData *firstPixmap;
};
QVGSharedContext::QVGSharedContext()
: context(0)
, refCount(0)
+ , widgetRefCount(0)
, engine(0)
, surface(EGL_NO_SURFACE)
+ , firstPixmap(0)
{
}
@@ -154,6 +159,28 @@ void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
Q_UNUSED(engine);
}
+void qt_vg_register_pixmap(QVGPixmapData *pd)
+{
+ QVGSharedContext *shared = sharedContext();
+ pd->next = shared->firstPixmap;
+ pd->prev = 0;
+ if (shared->firstPixmap)
+ shared->firstPixmap->prev = pd;
+ shared->firstPixmap = pd;
+}
+
+void qt_vg_unregister_pixmap(QVGPixmapData *pd)
+{
+ if (pd->next)
+ pd->next->prev = pd->prev;
+ if (pd->prev) {
+ pd->prev->next = pd->next;
+ } else {
+ QVGSharedContext *shared = sharedContext();
+ shared->firstPixmap = pd->next;
+ }
+}
+
#else
QVGPaintEngine *qt_vg_create_paint_engine(void)
@@ -166,6 +193,16 @@ void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
delete engine;
}
+void qt_vg_register_pixmap(QVGPixmapData *pd)
+{
+ Q_UNUSED(pd);
+}
+
+void qt_vg_unregister_pixmap(QVGPixmapData *pd)
+{
+ Q_UNUSED(pd);
+}
+
#endif
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
@@ -278,9 +315,11 @@ static QEglContext *createContext(QPaintDevice *device)
#if !defined(QVG_NO_SINGLE_CONTEXT)
-QEglContext *qt_vg_create_context(QPaintDevice *device)
+QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
{
QVGSharedContext *shared = sharedContext();
+ if (devType == QInternal::Widget)
+ ++(shared->widgetRefCount);
if (shared->context) {
++(shared->refCount);
return shared->context;
@@ -291,23 +330,68 @@ QEglContext *qt_vg_create_context(QPaintDevice *device)
}
}
-void qt_vg_destroy_context(QEglContext *context)
+static void qt_vg_destroy_shared_context(QVGSharedContext *shared)
+{
+ shared->context->makeCurrent(qt_vg_shared_surface());
+ delete shared->engine;
+ shared->engine = 0;
+ shared->context->doneCurrent();
+ if (shared->surface != EGL_NO_SURFACE) {
+ eglDestroySurface(shared->context->display(), shared->surface);
+ shared->surface = EGL_NO_SURFACE;
+ }
+ delete shared->context;
+ shared->context = 0;
+}
+
+void qt_vg_hibernate_pixmaps(QVGSharedContext *shared)
+{
+ // Artificially increase the reference count to prevent the
+ // context from being destroyed until after we have finished
+ // the hibernation process.
+ ++(shared->refCount);
+
+ // We need a context current to hibernate the VGImage objects.
+ shared->context->makeCurrent(qt_vg_shared_surface());
+
+ // Scan all QVGPixmapData objects in the system and hibernate them.
+ QVGPixmapData *pd = shared->firstPixmap;
+ while (pd != 0) {
+ pd->hibernate();
+ pd = pd->next;
+ }
+
+ // Hibernate any remaining VGImage's in the image pool.
+ QVGImagePool::instance()->hibernate();
+
+ // Don't need the current context any more.
+ shared->context->lazyDoneCurrent();
+
+ // Decrease the reference count and destroy the context if necessary.
+ if (--(shared->refCount) <= 0)
+ qt_vg_destroy_shared_context(shared);
+}
+
+void qt_vg_destroy_context(QEglContext *context, int devType)
{
QVGSharedContext *shared = sharedContext();
if (shared->context != context) {
// This is not the shared context. Shouldn't happen!
delete context;
- } else if (--(shared->refCount) <= 0) {
- shared->context->makeCurrent(qt_vg_shared_surface());
- delete shared->engine;
- shared->engine = 0;
- shared->context->doneCurrent();
- if (shared->surface != EGL_NO_SURFACE) {
- eglDestroySurface(shared->context->display(), shared->surface);
- shared->surface = EGL_NO_SURFACE;
- }
- delete shared->context;
- shared->context = 0;
+ return;
+ }
+ if (devType == QInternal::Widget)
+ --(shared->widgetRefCount);
+ if (--(shared->refCount) <= 0) {
+ qt_vg_destroy_shared_context(shared);
+ } else if (shared->widgetRefCount <= 0 && devType == QInternal::Widget) {
+ // All of the widget window surfaces have been destroyed
+ // but we still have VG 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_vg_hibernate_pixmaps(shared);
}
}
@@ -338,13 +422,15 @@ EGLSurface qt_vg_shared_surface(void)
#else
-QEglContext *qt_vg_create_context(QPaintDevice *device)
+QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
{
+ Q_UNUSED(devType);
return createContext(device);
}
-void qt_vg_destroy_context(QEglContext *context)
+void qt_vg_destroy_context(QEglContext *context, int devType)
{
+ Q_UNUSED(devType);
delete context;
}
@@ -434,7 +520,7 @@ QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage()
}
if (windowSurface != EGL_NO_SURFACE)
context->destroySurface(windowSurface);
- qt_vg_destroy_context(context);
+ qt_vg_destroy_context(context, QInternal::Widget);
}
}
@@ -453,7 +539,7 @@ QEglContext *QVGEGLWindowSurfaceVGImage::ensureContext(QWidget *widget)
if (!context) {
// Create a new EGL context. We create the surface in beginPaint().
size = newSize;
- context = qt_vg_create_context(widget);
+ context = qt_vg_create_context(widget, QInternal::Widget);
if (!context)
return 0;
isPaintingActive = false;
@@ -548,7 +634,7 @@ QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect()
if (context) {
if (windowSurface != EGL_NO_SURFACE)
context->destroySurface(windowSurface);
- qt_vg_destroy_context(context);
+ qt_vg_destroy_context(context, QInternal::Widget);
}
}
@@ -587,7 +673,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
qt_vg_destroy_paint_engine(engine);
engine = 0;
context->destroySurface(windowSurface);
- qt_vg_destroy_context(context);
+ qt_vg_destroy_context(context, QInternal::Widget);
context = 0;
windowSurface = EGL_NO_SURFACE;
}
@@ -596,7 +682,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
if (!context) {
// Create a new EGL context and bind it to the widget surface.
size = newSize;
- context = qt_vg_create_context(widget);
+ context = qt_vg_create_context(widget, QInternal::Widget);
if (!context)
return 0;
// We want a direct to window rendering surface if possible.
@@ -613,7 +699,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
#endif
EGLSurface surface = context->createSurface(widget, &surfaceProps);
if (surface == EGL_NO_SURFACE) {
- qt_vg_destroy_context(context);
+ qt_vg_destroy_context(context, QInternal::Widget);
context = 0;
return 0;
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 4cb0184..bb26d29 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -958,47 +958,47 @@ struct FlagDescription {
};
static const FlagDescription accelerationDescriptions[] = {
- { " DFXL_NONE ", DFXL_NONE },
- { " DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
- { " DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
- { " DFXL_DRAWLINE", DFXL_DRAWLINE },
- { " DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
- { " DFXL_BLIT", DFXL_BLIT },
- { " DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
- { " DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
- { " DFXL_DRAWSTRING", DFXL_DRAWSTRING },
+ { "DFXL_NONE", DFXL_NONE },
+ { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
+ { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
+ { "DFXL_DRAWLINE", DFXL_DRAWLINE },
+ { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
+ { "DFXL_BLIT", DFXL_BLIT },
+ { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
+ { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
+ { "DFXL_DRAWSTRING", DFXL_DRAWSTRING },
{ 0, 0 }
};
static const FlagDescription blitDescriptions[] = {
- { " DSBLIT_NOFX", DSBLIT_NOFX },
- { " DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
- { " DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
- { " DSBLIT_COLORIZE", DSBLIT_COLORIZE },
- { " DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
- { " DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
- { " DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
- { " DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
- { " DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
- { " DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
+ { "DSBLIT_NOFX", DSBLIT_NOFX },
+ { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
+ { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
+ { "DSBLIT_COLORIZE", DSBLIT_COLORIZE },
+ { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
+ { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
+ { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
+ { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
+ { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
+ { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
#if (Q_DIRECTFB_VERSION >= 0x000923)
- { " DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
- { " DSBLIT_XOR", DSBLIT_XOR },
+ { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
+ { "DSBLIT_XOR", DSBLIT_XOR },
#endif
#if (Q_DIRECTFB_VERSION >= 0x010000)
- { " DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
+ { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
#endif
{ 0, 0 }
};
static const FlagDescription drawDescriptions[] = {
- { " DSDRAW_NOFX", DSDRAW_NOFX },
- { " DSDRAW_BLEND", DSDRAW_BLEND },
- { " DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
- { " DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
- { " DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
- { " DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
- { " DSDRAW_XOR", DSDRAW_XOR },
+ { "DSDRAW_NOFX", DSDRAW_NOFX },
+ { "DSDRAW_BLEND", DSDRAW_BLEND },
+ { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
+ { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
+ { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
+ { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
+ { "DSDRAW_XOR", DSDRAW_XOR },
{ 0, 0 }
};
#endif
@@ -1063,7 +1063,7 @@ static inline bool setIntOption(const QStringList &arguments, const QString &var
static inline QColor colorFromName(const QString &name)
{
- QRegExp rx("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])");
+ QRegExp rx(QLatin1String("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"));
rx.setCaseSensitivity(Qt::CaseInsensitive);
if (rx.exactMatch(name)) {
Q_ASSERT(rx.captureCount() == 4);
@@ -1259,11 +1259,14 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
setIntOption(displayArgs, QLatin1String("height"), &h);
#ifndef QT_NO_DIRECTFB_LAYER
- result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, DLID_PRIMARY,
+ int layerId = DLID_PRIMARY;
+ setIntOption(displayArgs, QLatin1String("layerid"), &layerId);
+
+ result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId),
&d_ptr->dfbLayer);
if (result != DFB_OK) {
DirectFBError("QDirectFBScreen::connect: "
- "Unable to get primary display layer!", result);
+ "Unable to get display layer!", result);
return false;
}
result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen);
@@ -1275,7 +1278,14 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
#ifdef QT_NO_DIRECTFB_WM
result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
#elif (Q_DIRECTFB_VERSION >= 0x010000)
- result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
+ IDirectFBSurface *layerSurface;
+ if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) != DFB_OK) {
+ result = layerSurface->GetSize(layerSurface, &w, &h);
+ layerSurface->Release(layerSurface);
+ }
+ if (w <= 0 || h <= 0) {
+ result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
+ }
#else
qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n"
"query the size of the primary surface in windowed mode. You have to specify\n"
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index 021d52e..b79418a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -128,7 +128,6 @@ IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0));
}
-
void QDirectFBWindowSurface::createWindow(const QRect &rect)
{
IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
@@ -169,6 +168,9 @@ void QDirectFBWindowSurface::createWindow(const QRect &rect)
DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
if (window()) {
+ if (window()->windowFlags() & Qt::WindowStaysOnTopHint) {
+ dfbWindow->SetStackingClass(dfbWindow, DWSC_UPPER);
+ }
DFBWindowID winid;
result = dfbWindow->GetID(dfbWindow, &winid);
if (result != DFB_OK) {
diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp
index c95b63c..dee0e52 100644
--- a/src/plugins/imageformats/gif/qgifhandler.cpp
+++ b/src/plugins/imageformats/gif/qgifhandler.cpp
@@ -54,6 +54,10 @@ QT_BEGIN_NAMESPACE
#define Q_TRANSPARENT 0x00ffffff
+// avoid going through QImage::scanLine() which calls detach
+#define FAST_SCAN_LINE(bits, bpl, y) (bits + (y) * bpl)
+
+
/*
Incremental image decoder for GIF image format.
@@ -135,7 +139,7 @@ private:
int frame;
bool out_of_bounds;
bool digress;
- void nextY(QImage *image);
+ void nextY(unsigned char *bits, int bpl);
void disposePrevious(QImage *image);
};
@@ -232,6 +236,10 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
// CompuServe Incorporated. GIF(sm) is a Service Mark property of
// CompuServe Incorporated."
+ image->detach();
+ int bpl = image->bytesPerLine();
+ unsigned char *bits = image->bits();
+
#define LM(l, m) (((m)<<8)|l)
digress = false;
const int initial = length;
@@ -335,7 +343,9 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
QImage::Format format = trans_index >= 0 ? QImage::Format_ARGB32 : QImage::Format_RGB32;
if (image->isNull()) {
(*image) = QImage(swidth, sheight, format);
- memset(image->bits(), 0, image->byteCount());
+ bpl = image->bytesPerLine();
+ bits = image->bits();
+ memset(bits, 0, image->byteCount());
// ### size of the upcoming frame, should rather
// be known before decoding it.
@@ -393,11 +403,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
backingstore = QImage(qMax(backingstore.width(), w),
qMax(backingstore.height(), h),
QImage::Format_RGB32);
- memset(image->bits(), 0, image->byteCount());
+ memset(bits, 0, image->byteCount());
}
+ const int dest_bpl = backingstore.bytesPerLine();
+ unsigned char *dest_data = backingstore.bits();
for (int ln=0; ln<h; ln++) {
- memcpy(backingstore.scanLine(ln),
- image->scanLine(t+ln)+l, w*sizeof(QRgb));
+ memcpy(FAST_SCAN_LINE(dest_data, dest_bpl, ln),
+ FAST_SCAN_LINE(bits, bpl, t+ln) + l, w*sizeof(QRgb));
}
}
@@ -470,14 +482,14 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
if (needfirst) {
firstcode=oldcode=code;
if (!out_of_bounds && image->height() > y && firstcode!=trans_index)
- ((QRgb*)image->scanLine(y))[x] = color(firstcode);
+ ((QRgb*)FAST_SCAN_LINE(bits, bpl, y))[x] = color(firstcode);
x++;
if (x>=swidth) out_of_bounds = true;
needfirst=false;
if (x>=left+width) {
x=left;
out_of_bounds = left>=swidth || y>=sheight;
- nextY(image);
+ nextY(bits, bpl);
}
} else {
incode=code;
@@ -515,7 +527,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
const QRgb *map = lcmap ? localcmap : globalcmap;
QRgb *line = 0;
if (!out_of_bounds && h > y)
- line = (QRgb*)image->scanLine(y);
+ line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y);
while (sp>stack) {
const uchar index = *(--sp);
if (!out_of_bounds && h > y && index!=trans_index) {
@@ -529,9 +541,9 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
if (x>=left+width) {
x=left;
out_of_bounds = left>=swidth || y>=sheight;
- nextY(image);
+ nextY(bits, bpl);
if (!out_of_bounds && h > y)
- line = (QRgb*)image->scanLine(y);
+ line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y);
}
}
}
@@ -644,7 +656,7 @@ void QGIFFormat::fillRect(QImage *image, int col, int row, int w, int h, QRgb co
}
}
-void QGIFFormat::nextY(QImage *image)
+void QGIFFormat::nextY(unsigned char *bits, int bpl)
{
int my;
switch (interlace) {
@@ -660,7 +672,7 @@ void QGIFFormat::nextY(QImage *image)
// Don't dup with transparency
if (trans_index < 0) {
for (i=1; i<=my; i++) {
- memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb),
+ memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb),
(right-left+1)*sizeof(QRgb));
}
}
@@ -689,7 +701,7 @@ void QGIFFormat::nextY(QImage *image)
// Don't dup with transparency
if (trans_index < 0) {
for (i=1; i<=my; i++) {
- memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb),
+ memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb),
(right-left+1)*sizeof(QRgb));
}
}
@@ -713,7 +725,7 @@ void QGIFFormat::nextY(QImage *image)
// Don't dup with transparency
if (trans_index < 0) {
for (i=1; i<=my; i++) {
- memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb),
+ memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb),
(right-left+1)*sizeof(QRgb));
}
}
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 54bbcda..11608ef 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -84,15 +84,12 @@ class QImageSmoothScaler
public:
QImageSmoothScaler(const int w, const int h, const QImage &src);
QImageSmoothScaler(const int srcWidth, const int srcHeight,
- const char *parameters);
+ const int dstWidth, const int dstHeight);
virtual ~QImageSmoothScaler(void);
QImage scale();
-protected:
- int scaledWidth(void) const;
-
private:
QImageSmoothScalerPrivate *d;
virtual QRgb *scanLine(const int line = 0, const QImage *src = 0);
@@ -123,33 +120,9 @@ QImageSmoothScaler::QImageSmoothScaler(const int w, const int h,
}
QImageSmoothScaler::QImageSmoothScaler(const int srcWidth, const int srcHeight,
- const char *parameters)
+ const int dstWidth, const int dstHeight)
{
- char sModeStr[1024];
- int t1;
- int t2;
- int dstWidth;
- int dstHeight;
-
- sModeStr[0] = '\0';
-
d = new QImageSmoothScalerPrivate;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
- sscanf_s(parameters, "Scale( %i, %i, %1023s )", &dstWidth, &dstHeight, sModeStr, sizeof(sModeStr));
-#else
- sscanf(parameters, "Scale( %i, %i, %s )", &dstWidth, &dstHeight, sModeStr);
-#endif
- QString sModeQStr = QString::fromLatin1(sModeStr);
-
- t1 = srcWidth * dstHeight;
- t2 = srcHeight * dstWidth;
-
- if (((sModeQStr == QLatin1String("ScaleMin")) && (t1 > t2)) || ((sModeQStr == QLatin1String("ScaleMax")) && (t2 < t2))) {
- dstHeight = t2 / srcWidth;
- } else if (sModeQStr != QLatin1String("ScaleFree")) {
- dstWidth = t1 / srcHeight;
- }
-
d->setup(srcWidth, srcHeight, dstWidth, dstHeight, 0);
}
@@ -164,11 +137,6 @@ void QImageSmoothScalerPrivate::setup(const int srcWidth, const int srcHeight,
hasAlpha = hasAlphaChannel;
}
-int QImageSmoothScaler::scaledWidth() const
-{
- return d->cols;
-}
-
QImageSmoothScaler::~QImageSmoothScaler()
{
delete d;
@@ -467,20 +435,18 @@ QImage QImageSmoothScaler::scale()
class jpegSmoothScaler : public QImageSmoothScaler
{
public:
- jpegSmoothScaler(struct jpeg_decompress_struct *info, const char *params):
- QImageSmoothScaler(info->output_width, info->output_height, params)
+ jpegSmoothScaler(struct jpeg_decompress_struct *info, const QSize& dstSize, const QRect& clipRect)
+ : QImageSmoothScaler(clipRect.width(), clipRect.height(),
+ dstSize.width(), dstSize.height())
{
- cinfo = info;
- cols24Bit = scaledWidth() * 3;
-
- cacheHeight = 1;
- imageCache = QImage( info->output_width, cacheHeight, QImage::Format_RGB32 );
+ cinfo = info;
+ clip = clipRect;
+ imageCache = QImage(info->output_width, 1, QImage::Format_RGB32);
}
private:
- int cols24Bit;
+ QRect clip;
QImage imageCache;
- int cacheHeight;
struct jpeg_decompress_struct *cinfo;
QRgb *scanLine(const int line = 0, const QImage *src = 0)
@@ -492,33 +458,42 @@ private:
Q_UNUSED(src);
uchar* data = imageCache.bits();
+
+ // Read ahead if we haven't reached the first clipped scanline yet.
+ while (int(cinfo->output_scanline) < clip.y() &&
+ cinfo->output_scanline < cinfo->output_height)
+ jpeg_read_scanlines(cinfo, &data, 1);
+
+ // Read the next scanline. We assume that "line"
+ // will never be >= clip.height().
jpeg_read_scanlines(cinfo, &data, 1);
- out = (QRgb*)imageCache.scanLine(0);
+ if (cinfo->output_scanline == cinfo->output_height)
+ jpeg_finish_decompress(cinfo);
+
+ out = ((QRgb*)data) + clip.x();
//
// The smooth scale algorithm only works on 32-bit images;
// convert from (8|24) bits to 32.
//
if (cinfo->output_components == 1) {
- in = (uchar*)out + scaledWidth();
- for (uint i = scaledWidth(); i--; ) {
- in--;
+ in = data + clip.right();
+ for (int i = clip.width(); i--; ) {
out[i] = qRgb(*in, *in, *in);
+ in--;
}
- } else if (cinfo->out_color_space == JCS_CMYK) {
- int cols32Bit = scaledWidth() * 4;
- in = (uchar*)out + cols32Bit;
- for (uint i = scaledWidth(); i--; ) {
- in -= 4;
- int k = in[3];
- out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);
- //out[i] = qRgb(in[0], in[1], in[2]);
- }
- } else {
- in = (uchar*)out + cols24Bit;
- for (uint i = scaledWidth(); i--; ) {
- in -= 3;
+ } else if (cinfo->out_color_space == JCS_CMYK) {
+ in = data + clip.right() * 4;
+ for (int i = clip.width(); i--; ) {
+ int k = in[3];
+ out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);
+ in -= 4;
+ }
+ } else {
+ in = data + clip.right() * 3;
+ for (int i = clip.width(); i--; ) {
out[i] = qRgb(in[0], in[1], in[2]);
+ in -= 3;
}
}
@@ -637,18 +612,6 @@ inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device)
}
-static void scaleSize(int &reqW, int &reqH, int imgW, int imgH, Qt::AspectRatioMode mode)
-{
- if (mode == Qt::IgnoreAspectRatio)
- return;
- int t1 = imgW * reqH;
- int t2 = reqW * imgH;
- if ((mode == Qt::KeepAspectRatio && (t1 > t2)) || (mode == Qt::KeepAspectRatioByExpanding && (t1 < t2)))
- reqH = t2 / imgW;
- else
- reqW = t1 / imgH;
-}
-
static bool read_jpeg_size(QIODevice *device, int &w, int &h)
{
bool rt = false;
@@ -729,7 +692,7 @@ static bool read_jpeg_format(QIODevice *device, QImage::Format &format)
}
static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
- bool dummy = false)
+ const QSize& size)
{
QImage::Format format;
switch (info->output_components) {
@@ -744,13 +707,8 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
return false; // unsupported format
}
- const QSize size(info->output_width, info->output_height);
if (dest->size() != size || dest->format() != format) {
- static uchar dummyImage[1];
- if (dummy) // Create QImage but don't read the pixels
- *dest = QImage(dummyImage, size.width(), size.height(), format);
- else
- *dest = QImage(size, format);
+ *dest = QImage(size, format);
if (format == QImage::Format_Indexed8) {
dest->setColorCount(256);
@@ -763,13 +721,9 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
}
static bool read_jpeg_image(QIODevice *device, QImage *outImage,
- const QByteArray &parameters, QSize scaledSize,
- int inQuality )
+ QSize scaledSize, QRect scaledClipRect,
+ QRect clipRect, int inQuality )
{
-#ifdef QT_NO_IMAGE_SMOOTHSCALE
- Q_UNUSED( scaledSize );
-#endif
-
struct jpeg_decompress_struct cinfo;
struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device);
@@ -794,18 +748,53 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
if (quality < 0)
quality = 75;
- QString params = QString::fromLatin1(parameters);
- params.simplified();
- int sWidth = 0, sHeight = 0;
- char sModeStr[1024] = "";
- Qt::AspectRatioMode sMode;
+ // If possible, merge the scaledClipRect into either scaledSize
+ // or clipRect to avoid doing a separate scaled clipping pass.
+ // Best results are achieved by clipping before scaling, not after.
+ if (!scaledClipRect.isEmpty()) {
+ if (scaledSize.isEmpty() && clipRect.isEmpty()) {
+ // No clipping or scaling before final clip.
+ clipRect = scaledClipRect;
+ scaledClipRect = QRect();
+ } else if (scaledSize.isEmpty()) {
+ // Clipping, but no scaling: combine the clip regions.
+ scaledClipRect.translate(clipRect.topLeft());
+ clipRect = scaledClipRect.intersected(clipRect);
+ scaledClipRect = QRect();
+ } else if (clipRect.isEmpty()) {
+ // No clipping, but scaling: if we can map back to an
+ // integer pixel boundary, then clip before scaling.
+ if ((cinfo.image_width % scaledSize.width()) == 0 &&
+ (cinfo.image_height % scaledSize.height()) == 0) {
+ int x = scaledClipRect.x() * cinfo.image_width /
+ scaledSize.width();
+ int y = scaledClipRect.y() * cinfo.image_height /
+ scaledSize.height();
+ int width = (scaledClipRect.right() + 1) *
+ cinfo.image_width / scaledSize.width() - x;
+ int height = (scaledClipRect.bottom() + 1) *
+ cinfo.image_height / scaledSize.height() - y;
+ clipRect = QRect(x, y, width, height);
+ scaledSize = scaledClipRect.size();
+ scaledClipRect = QRect();
+ }
+ } else {
+ // Clipping and scaling: too difficult to figure out,
+ // and not a likely use case, so do it the long way.
+ }
+ }
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
- // If high quality not required, shrink image during decompression
- if (scaledSize.isValid() && !scaledSize.isEmpty() && quality < HIGH_QUALITY_THRESHOLD
- && !params.contains(QLatin1String("GetHeaderInformation")) ) {
- cinfo.scale_denom = qMin(cinfo.image_width / scaledSize.width(),
- cinfo.image_width / scaledSize.height());
+ // Determine the scale factor to pass to libjpeg for quick downscaling.
+ if (!scaledSize.isEmpty()) {
+ if (clipRect.isEmpty()) {
+ cinfo.scale_denom =
+ qMin(cinfo.image_width / scaledSize.width(),
+ cinfo.image_height / scaledSize.height());
+ } else {
+ cinfo.scale_denom =
+ qMin(clipRect.width() / scaledSize.width(),
+ clipRect.height() / scaledSize.height());
+ }
if (cinfo.scale_denom < 2) {
cinfo.scale_denom = 1;
} else if (cinfo.scale_denom < 4) {
@@ -816,9 +805,19 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
cinfo.scale_denom = 8;
}
cinfo.scale_num = 1;
+ if (!clipRect.isEmpty()) {
+ // Correct the scale factor so that we clip accurately.
+ // It is recommended that the clip rectangle be aligned
+ // on an 8-pixel boundary for best performance.
+ while (cinfo.scale_denom > 1 &&
+ ((clipRect.x() % cinfo.scale_denom) != 0 ||
+ (clipRect.y() % cinfo.scale_denom) != 0 ||
+ (clipRect.width() % cinfo.scale_denom) != 0 ||
+ (clipRect.height() % cinfo.scale_denom) != 0)) {
+ cinfo.scale_denom /= 2;
+ }
+ }
}
-#endif
-
// If high quality not required, use fast decompression
if( quality < HIGH_QUALITY_THRESHOLD ) {
@@ -826,132 +825,102 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
cinfo.do_fancy_upsampling = FALSE;
}
+ (void) jpeg_calc_output_dimensions(&cinfo);
- (void) jpeg_start_decompress(&cinfo);
+ // Determine the clip region to extract.
+ QRect imageRect(0, 0, cinfo.output_width, cinfo.output_height);
+ QRect clip;
+ if (clipRect.isEmpty()) {
+ clip = imageRect;
+ } else if (cinfo.scale_denom == 1) {
+ clip = clipRect.intersected(imageRect);
+ } else {
+ // The scale factor was corrected above to ensure that
+ // we don't miss pixels when we scale the clip rectangle.
+ clip = QRect(clipRect.x() / int(cinfo.scale_denom),
+ clipRect.y() / int(cinfo.scale_denom),
+ clipRect.width() / int(cinfo.scale_denom),
+ clipRect.height() / int(cinfo.scale_denom));
+ clip = clip.intersected(imageRect);
+ }
- if (params.contains(QLatin1String("GetHeaderInformation"))) {
- if (!ensureValidImage(outImage, &cinfo, true))
- longjmp(jerr.setjmp_buffer, 1);
- } else if (params.contains(QLatin1String("Scale"))) {
-#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE)
- sscanf_s(params.toLatin1().data(), "Scale(%i, %i, %1023s)",
- &sWidth, &sHeight, sModeStr, sizeof(sModeStr));
-#else
- sscanf(params.toLatin1().data(), "Scale(%i, %i, %1023s)",
- &sWidth, &sHeight, sModeStr);
-#endif
+#ifndef QT_NO_IMAGE_SMOOTHSCALE
+ if (scaledSize.isValid() && scaledSize != clip.size()
+ && quality >= HIGH_QUALITY_THRESHOLD) {
- QString sModeQStr(QString::fromLatin1(sModeStr));
- if (sModeQStr == QLatin1String("IgnoreAspectRatio")) {
- sMode = Qt::IgnoreAspectRatio;
- } else if (sModeQStr == QLatin1String("KeepAspectRatio")) {
- sMode = Qt::KeepAspectRatio;
- } else if (sModeQStr == QLatin1String("KeepAspectRatioByExpanding")) {
- sMode = Qt::KeepAspectRatioByExpanding;
- } else {
- qDebug("read_jpeg_image: invalid aspect ratio mode \"%s\", see QImage::AspectRatioMode documentation", sModeStr);
- sMode = Qt::KeepAspectRatio;
- }
+ (void) jpeg_start_decompress(&cinfo);
-// qDebug("Parameters ask to scale the image to %i x %i AspectRatioMode: %s", sWidth, sHeight, sModeStr);
- scaleSize(sWidth, sHeight, cinfo.output_width, cinfo.output_height, sMode);
-// qDebug("Scaling the jpeg to %i x %i", sWidth, sHeight, sModeStr);
-
- if (cinfo.output_components == 3 || cinfo.output_components == 4) {
- if (outImage->size() != QSize(sWidth, sHeight) || outImage->format() != QImage::Format_RGB32)
- *outImage = QImage(sWidth, sHeight, QImage::Format_RGB32);
- } else if (cinfo.output_components == 1) {
- if (outImage->size() != QSize(sWidth, sHeight) || outImage->format() != QImage::Format_Indexed8)
- *outImage = QImage(sWidth, sHeight, QImage::Format_Indexed8);
- outImage->setColorCount(256);
- for (int i = 0; i < 256; ++i)
- outImage->setColor(i, qRgb(i,i,i));
- } else {
- // Unsupported format
- }
- if (outImage->isNull())
+ jpegSmoothScaler scaler(&cinfo, scaledSize, clip);
+ *outImage = scaler.scale();
+ } else
+#endif
+ {
+ // Allocate memory for the clipped QImage.
+ if (!ensureValidImage(outImage, &cinfo, clip.size()))
longjmp(jerr.setjmp_buffer, 1);
- if (!outImage->isNull()) {
- QImage tmpImage(cinfo.output_width, 1, QImage::Format_RGB32);
- uchar* inData = tmpImage.bits();
- uchar* outData = outImage->bits();
- int out_bpl = outImage->bytesPerLine();
+ // Avoid memcpy() overhead if grayscale with no clipping.
+ bool quickGray = (cinfo.output_components == 1 &&
+ clip == imageRect);
+ if (!quickGray) {
+ // Ask the jpeg library to allocate a temporary row.
+ // The library will automatically delete it for us later.
+ // The libjpeg docs say we should do this before calling
+ // jpeg_start_decompress(). We can't use "new" here
+ // because we are inside the setjmp() block and an error
+ // in the jpeg input stream would cause a memory leak.
+ JSAMPARRAY rows = (cinfo.mem->alloc_sarray)
+ ((j_common_ptr)&cinfo, JPOOL_IMAGE,
+ cinfo.output_width * cinfo.output_components, 1);
+
+ (void) jpeg_start_decompress(&cinfo);
+
while (cinfo.output_scanline < cinfo.output_height) {
- int outputLine = sHeight * cinfo.output_scanline / cinfo.output_height;
- (void) jpeg_read_scanlines(&cinfo, &inData, 1);
+ int y = int(cinfo.output_scanline) - clip.y();
+ if (y >= clip.height())
+ break; // We've read the entire clip region, so abort.
+
+ (void) jpeg_read_scanlines(&cinfo, rows, 1);
+
+ if (y < 0)
+ continue; // Haven't reached the starting line yet.
+
if (cinfo.output_components == 3) {
- uchar *in = inData;
- QRgb *out = (QRgb*)outData + outputLine * out_bpl;
- for (uint i=0; i<cinfo.output_width; i++) {
-// ### Only scaling down an image works, I don't think scaling up will work at the moment
-// ### An idea I have to make this a smooth scale is to progressively add the pixel values up
-// When scaling down, multiple values are being over drawn in to the output buffer.
-// Instead, a weighting based on the distance the line or pixel is from the output pixel determines
-// the weight of it when added to the output buffer. At present it is a non-smooth scale which is
-// inefficently implemented, it still uncompresses all the jpeg, an optimization for progressive
-// jpegs could be made if scaling by say 50% or some other special cases
- out[sWidth * i / cinfo.output_width] = qRgb(in[0], in[1], in[2]);
+ // Expand 24->32 bpp.
+ uchar *in = rows[0] + clip.x() * 3;
+ QRgb *out = (QRgb*)outImage->scanLine(y);
+ for (int i = 0; i < clip.width(); ++i) {
+ *out++ = qRgb(in[0], in[1], in[2]);
in += 3;
}
- } else {
-// ### Need to test the case where the jpeg is grayscale, need some black and white jpegs to test
-// this code. (also only scales down and probably won't scale to a larger size)
- uchar *in = inData;
- uchar *out = outData + outputLine*out_bpl;
- for (uint i=0; i<cinfo.output_width; i++) {
- out[sWidth * i / cinfo.output_width] = in[i];
+ } else if (cinfo.out_color_space == JCS_CMYK) {
+ // Convert CMYK->RGB.
+ uchar *in = rows[0] + clip.x() * 4;
+ QRgb *out = (QRgb*)outImage->scanLine(y);
+ for (int i = 0; i < clip.width(); ++i) {
+ int k = in[3];
+ *out++ = qRgb(k * in[0] / 255, k * in[1] / 255,
+ k * in[2] / 255);
+ in += 4;
}
+ } else if (cinfo.output_components == 1) {
+ // Grayscale.
+ memcpy(outImage->scanLine(y),
+ rows[0] + clip.x(), clip.width());
}
}
- (void) jpeg_finish_decompress(&cinfo);
- }
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
- } else if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height)
- && quality >= HIGH_QUALITY_THRESHOLD) {
-
- jpegSmoothScaler scaler(&cinfo, QString().sprintf("Scale( %d, %d, ScaleFree )",
- scaledSize.width(),
- scaledSize.height()).toLatin1().data());
- *outImage = scaler.scale();
-#endif
- } else {
- if (!ensureValidImage(outImage, &cinfo))
- longjmp(jerr.setjmp_buffer, 1);
-
- uchar* data = outImage->bits();
- int bpl = outImage->bytesPerLine();
- while (cinfo.output_scanline < cinfo.output_height) {
- uchar *d = data + cinfo.output_scanline * bpl;
- (void) jpeg_read_scanlines(&cinfo,
- &d,
- 1);
+ } else {
+ // Load unclipped grayscale data directly into the QImage.
+ (void) jpeg_start_decompress(&cinfo);
+ while (cinfo.output_scanline < cinfo.output_height) {
+ uchar *row = outImage->scanLine(cinfo.output_scanline);
+ (void) jpeg_read_scanlines(&cinfo, &row, 1);
+ }
}
- (void) jpeg_finish_decompress(&cinfo);
- if (cinfo.output_components == 3) {
- // Expand 24->32 bpp.
- for (uint j=0; j<cinfo.output_height; j++) {
- uchar *in = outImage->scanLine(j) + cinfo.output_width * 3;
- QRgb *out = (QRgb*)outImage->scanLine(j);
+ if (cinfo.output_scanline == cinfo.output_height)
+ (void) jpeg_finish_decompress(&cinfo);
- for (uint i=cinfo.output_width; i--;) {
- in-=3;
- out[i] = qRgb(in[0], in[1], in[2]);
- }
- }
- } else if (cinfo.out_color_space == JCS_CMYK) {
- for (uint j = 0; j < cinfo.output_height; ++j) {
- uchar *in = outImage->scanLine(j) + cinfo.output_width * 4;
- QRgb *out = (QRgb*)outImage->scanLine(j);
-
- for (uint i = cinfo.output_width; i--; ) {
- in-=4;
- int k = in[3];
- out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);
- }
- }
- }
if (cinfo.density_unit == 1) {
outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));
outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));
@@ -960,13 +929,15 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
outImage->setDotsPerMeterY(int(100. * cinfo.Y_density));
}
- if (scaledSize.isValid() && scaledSize != QSize(cinfo.output_width, cinfo.output_height))
+ if (scaledSize.isValid() && scaledSize != clip.size())
*outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation);
}
}
jpeg_destroy_decompress(&cinfo);
delete iod_src;
+ if (!scaledClipRect.isEmpty())
+ *outImage = outImage->copy(scaledClipRect);
return !outImage->isNull();
}
@@ -1224,7 +1195,7 @@ bool QJpegHandler::read(QImage *image)
{
if (!canRead())
return false;
- return read_jpeg_image(device(), image, parameters, scaledSize, quality);
+ return read_jpeg_image(device(), image, scaledSize, scaledClipRect, clipRect, quality);
}
bool QJpegHandler::write(const QImage &image)
@@ -1235,9 +1206,9 @@ bool QJpegHandler::write(const QImage &image)
bool QJpegHandler::supportsOption(ImageOption option) const
{
return option == Quality
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
|| option == ScaledSize
-#endif
+ || option == ScaledClipRect
+ || option == ClipRect
|| option == Size
|| option == ImageFormat;
}
@@ -1246,10 +1217,12 @@ QVariant QJpegHandler::option(ImageOption option) const
{
if (option == Quality) {
return quality;
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
} else if (option == ScaledSize) {
return scaledSize;
-#endif
+ } else if (option == ScaledClipRect) {
+ return scaledClipRect;
+ } else if (option == ClipRect) {
+ return clipRect;
} else if (option == Size) {
if (canRead() && !device()->isSequential()) {
qint64 pos = device()->pos();
@@ -1276,10 +1249,12 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
{
if (option == Quality)
quality = value.toInt();
-#ifndef QT_NO_IMAGE_SMOOTHSCALE
else if ( option == ScaledSize )
scaledSize = value.toSize();
-#endif
+ else if ( option == ScaledClipRect )
+ scaledClipRect = value.toRect();
+ else if ( option == ClipRect )
+ clipRect = value.toRect();
}
QByteArray QJpegHandler::name() const
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h
index 654c078..6870cd6 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.h
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.h
@@ -44,6 +44,7 @@
#include <QtGui/qimageiohandler.h>
#include <QtCore/QSize>
+#include <QtCore/QRect>
QT_BEGIN_NAMESPACE
@@ -66,8 +67,9 @@ public:
private:
int quality;
- QByteArray parameters;
QSize scaledSize;
+ QRect scaledClipRect;
+ QRect clipRect;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri
index a3abc98..b66f8f9 100644
--- a/src/plugins/qpluginbase.pri
+++ b/src/plugins/qpluginbase.pri
@@ -1,6 +1,6 @@
TEMPLATE = lib
isEmpty(QT_MAJOR_VERSION) {
- VERSION=4.6.0
+ VERSION=4.6.1
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/plugins/sqldrivers/sqldrivers.pro b/src/plugins/sqldrivers/sqldrivers.pro
index 2bd5f2c..83d71e4 100644
--- a/src/plugins/sqldrivers/sqldrivers.pro
+++ b/src/plugins/sqldrivers/sqldrivers.pro
@@ -10,6 +10,4 @@ contains(sql-plugins, sqlite) : SUBDIRS += sqlite
contains(sql-plugins, sqlite2) : SUBDIRS += sqlite2
contains(sql-plugins, ibase) : SUBDIRS += ibase
-contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
- symbian:contains(CONFIG, system-sqlite): SUBDIRS += sqlite_symbian
- }
+symbian:contains(CONFIG, system-sqlite): SUBDIRS += sqlite_symbian
diff --git a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro
index 9687908..691cce1 100644
--- a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro
+++ b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro
@@ -3,7 +3,7 @@ TEMPLATE = subdirs
# We just want to export the sqlite3 binaries for Symbian for platforms that do not have them.
symbian {
- !exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) {
+ !symbian_no_export_sqlite:!exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) {
BLD_INF_RULES.prj_exports += ":zip SQLite3_v9.2.zip"
}
}
diff --git a/src/qbase.pri b/src/qbase.pri
index 0aae24d..d1a2a75 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.6.0
+ VERSION=4.6.1
} else {
VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
}
diff --git a/src/qt_install.pri b/src/qt_install.pri
index ebeac8d..5b29942 100644
--- a/src/qt_install.pri
+++ b/src/qt_install.pri
@@ -30,6 +30,12 @@ qt_install_headers {
targ_headers.files = $$INSTALL_HEADERS
targ_headers.path = $$[QT_INSTALL_HEADERS]/$$TARGET
INSTALLS += targ_headers
+
+ contains(QT_CONFIG,private_tests) {
+ private_headers.files = $$SYNCQT.PRIVATE_HEADER_FILES
+ private_headers.path = $$[QT_INSTALL_HEADERS]/$$TARGET/private
+ INSTALLS += private_headers
+ }
}
embedded:equals(TARGET, QtGui) {
diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def
index 49c4361..fe752c8 100644
--- a/src/s60installs/bwins/QtCoreu.def
+++ b/src/s60installs/bwins/QtCoreu.def
@@ -2264,7 +2264,7 @@ EXPORTS
?isSequential@QIODevice@@UBE_NXZ @ 2263 NONAME ; bool QIODevice::isSequential(void) const
?isSequential@QIODevicePrivate@@QBE_NXZ @ 2264 NONAME ; bool QIODevicePrivate::isSequential(void) const
?isSequential@QProcess@@UBE_NXZ @ 2265 NONAME ; bool QProcess::isSequential(void) const
- ?isSignalConnected@QObjectPrivate@@QBE_NH@Z @ 2266 NONAME ; bool QObjectPrivate::isSignalConnected(int) const
+ ?isSignalConnected@QObjectPrivate@@QBE_NI@Z @ 2266 NONAME ; bool QObjectPrivate::isSignalConnected(unsigned int) const
?isSimpleText@QString@@QBE_NXZ @ 2267 NONAME ; bool QString::isSimpleText(void) const
?isSingleShot@QTimer@@QBE_NXZ @ 2268 NONAME ; bool QTimer::isSingleShot(void) const
?isSpace@QChar@@QBE_NXZ @ 2269 NONAME ; bool QChar::isSpace(void) const
diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index 166b6fe..7a629d7 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -271,7 +271,7 @@ EXPORTS
??0QImageIOHandler@@IAE@AAVQImageIOHandlerPrivate@@@Z @ 270 NONAME ; QImageIOHandler::QImageIOHandler(class QImageIOHandlerPrivate &)
??0QImageIOHandler@@QAE@XZ @ 271 NONAME ; QImageIOHandler::QImageIOHandler(void)
??0QImageIOPlugin@@QAE@PAVQObject@@@Z @ 272 NONAME ; QImageIOPlugin::QImageIOPlugin(class QObject *)
- ??0QImagePixmapCleanupHooks@@QAE@XZ @ 273 NONAME ; QImagePixmapCleanupHooks::QImagePixmapCleanupHooks(void)
+ ??0QImagePixmapCleanupHooks@@QAE@XZ @ 273 NONAME ABSENT ; QImagePixmapCleanupHooks::QImagePixmapCleanupHooks(void)
??0QImageReader@@QAE@ABVQString@@ABVQByteArray@@@Z @ 274 NONAME ; QImageReader::QImageReader(class QString const &, class QByteArray const &)
??0QImageReader@@QAE@PAVQIODevice@@ABVQByteArray@@@Z @ 275 NONAME ; QImageReader::QImageReader(class QIODevice *, class QByteArray const &)
??0QImageReader@@QAE@XZ @ 276 NONAME ; QImageReader::QImageReader(void)
@@ -2021,7 +2021,7 @@ EXPORTS
?addButton@QMessageBox@@QAEPAVQPushButton@@ABVQString@@W4ButtonRole@1@@Z @ 2020 NONAME ; class QPushButton * QMessageBox::addButton(class QString const &, enum QMessageBox::ButtonRole)
?addButton@QMessageBox@@QAEPAVQPushButton@@W4StandardButton@1@@Z @ 2021 NONAME ; class QPushButton * QMessageBox::addButton(enum QMessageBox::StandardButton)
?addButton@QMessageBox@@QAEXPAVQAbstractButton@@W4ButtonRole@1@@Z @ 2022 NONAME ; void QMessageBox::addButton(class QAbstractButton *, enum QMessageBox::ButtonRole)
- ?addCacheData@QVectorPath@@QAEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX1@Z@Z @ 2023 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(void *))
+ ?addCacheData@QVectorPath@@QAEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX1@Z@Z @ 2023 NONAME ABSENT ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(void *))
?addChild@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 2024 NONAME ; void QGraphicsItemPrivate::addChild(class QGraphicsItem *)
?addChild@QTreeWidgetItem@@QAEXPAV1@@Z @ 2025 NONAME ; void QTreeWidgetItem::addChild(class QTreeWidgetItem *)
?addChildLayout@QLayout@@IAEXPAV1@@Z @ 2026 NONAME ; void QLayout::addChildLayout(class QLayout *)
@@ -2503,7 +2503,7 @@ EXPORTS
?cacheMode@QMovie@@QAE?AW4CacheMode@1@XZ @ 2502 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void)
?cacheMode@QMovie@@QBE?AW4CacheMode@1@XZ @ 2503 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void) const
?cacheStatistics@QFont@@SAXXZ @ 2504 NONAME ; void QFont::cacheStatistics(void)
- ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const
+ ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ABSENT ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const
?calcEffectiveOpacity@QGraphicsItemPrivate@@QBEMXZ @ 2506 NONAME ; float QGraphicsItemPrivate::calcEffectiveOpacity(void) const
?calculateTabWidth@QTextEngine@@QBE?AUQFixed@@HU2@@Z @ 2507 NONAME ; struct QFixed QTextEngine::calculateTabWidth(int, struct QFixed) const
?calendarPopup@QDateTimeEdit@@QBE_NXZ @ 2508 NONAME ; bool QDateTimeEdit::calendarPopup(void) const
@@ -3724,7 +3724,7 @@ EXPORTS
?directory@QFileDialog@@QBE?AVQDir@@XZ @ 3723 NONAME ; class QDir QFileDialog::directory(void) const
?directoryEntered@QFileDialog@@IAEXABVQString@@@Z @ 3724 NONAME ; void QFileDialog::directoryEntered(class QString const &)
?dirtyRegionOffset@QAbstractItemView@@IBE?AVQPoint@@XZ @ 3725 NONAME ; class QPoint QAbstractItemView::dirtyRegionOffset(void) const
- ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N000@Z @ 3726 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool, bool) const
+ ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N000@Z @ 3726 NONAME ABSENT ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool, bool) const
?disconnectFromModel@QProxyModel@@IBEXPBVQAbstractItemModel@@@Z @ 3727 NONAME ; void QProxyModel::disconnectFromModel(class QAbstractItemModel const *) const
?dispatchEnterLeave@QApplicationPrivate@@SAXPAVQWidget@@0@Z @ 3728 NONAME ; void QApplicationPrivate::dispatchEnterLeave(class QWidget *, class QWidget *)
?display@QLCDNumber@@QAEXABVQString@@@Z @ 3729 NONAME ; void QLCDNumber::display(class QString const &)
@@ -4299,7 +4299,7 @@ EXPORTS
?expandingDirections@QSpacerItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4298 NONAME ; class QFlags<enum Qt::Orientation> QSpacerItem::expandingDirections(void) const
?expandingDirections@QWidgetItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4299 NONAME ; class QFlags<enum Qt::Orientation> QWidgetItem::expandingDirections(void) const
?expandsOnDoubleClick@QTreeView@@QBE_NXZ @ 4300 NONAME ; bool QTreeView::expandsOnDoubleClick(void) const
- ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ; void QFontEngine::expireGlyphCache(void)
+ ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ABSENT ; void QFontEngine::expireGlyphCache(void)
?extension@QDialog@@QBEPAVQWidget@@XZ @ 4302 NONAME ; class QWidget * QDialog::extension(void) const
?extension@QGraphicsEllipseItem@@MBE?AVQVariant@@ABV2@@Z @ 4303 NONAME ; class QVariant QGraphicsEllipseItem::extension(class QVariant const &) const
?extension@QGraphicsItem@@MBE?AVQVariant@@ABV2@@Z @ 4304 NONAME ; class QVariant QGraphicsItem::extension(class QVariant const &) const
@@ -4933,8 +4933,8 @@ EXPORTS
?globalY@QMouseEvent@@QBEHXZ @ 4932 NONAME ; int QMouseEvent::globalY(void) const
?globalY@QTabletEvent@@QBEHXZ @ 4933 NONAME ; int QTabletEvent::globalY(void) const
?globalY@QWheelEvent@@QBEHXZ @ 4934 NONAME ; int QWheelEvent::globalY(void) const
- ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const
- ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const
+ ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const
+ ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const
?glyphCount@QFontEngine@@UBEHXZ @ 4937 NONAME ; int QFontEngine::glyphCount(void) const
?glyphMargin@QTextureGlyphCache@@UBEHXZ @ 4938 NONAME ; int QTextureGlyphCache::glyphMargin(void) const
?gotFocus@QFocusEvent@@QBE_NXZ @ 4939 NONAME ; bool QFocusEvent::gotFocus(void) const
@@ -5522,8 +5522,8 @@ EXPORTS
?invalidateBuffer@QWidgetPrivate@@QAEXABVQRect@@@Z @ 5521 NONAME ; void QWidgetPrivate::invalidateBuffer(class QRect const &)
?invalidateBuffer@QWidgetPrivate@@QAEXABVQRegion@@@Z @ 5522 NONAME ; void QWidgetPrivate::invalidateBuffer(class QRegion const &)
?invalidateBuffer_resizeHelper@QWidgetPrivate@@QAEXABVQPoint@@ABVQSize@@@Z @ 5523 NONAME ; void QWidgetPrivate::invalidateBuffer_resizeHelper(class QPoint const &, class QSize const &)
- ?invalidateCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 5524 NONAME ; void QGraphicsItemPrivate::invalidateCachedClipPath(void)
- ?invalidateCachedClipPathRecursively@QGraphicsItemPrivate@@QAEX_NABVQRectF@@@Z @ 5525 NONAME ; void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool, class QRectF const &)
+ ?invalidateCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 5524 NONAME ABSENT ; void QGraphicsItemPrivate::invalidateCachedClipPath(void)
+ ?invalidateCachedClipPathRecursively@QGraphicsItemPrivate@@QAEX_NABVQRectF@@@Z @ 5525 NONAME ABSENT ; void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool, class QRectF const &)
?invalidateChildrenSceneTransform@QGraphicsItemPrivate@@QAEXXZ @ 5526 NONAME ; void QGraphicsItemPrivate::invalidateChildrenSceneTransform(void)
?invalidateDepthRecursively@QGraphicsItemPrivate@@QAEXXZ @ 5527 NONAME ; void QGraphicsItemPrivate::invalidateDepthRecursively(void)
?invalidateFilter@QSortFilterProxyModel@@IAEXXZ @ 5528 NONAME ; void QSortFilterProxyModel::invalidateFilter(void)
@@ -5589,7 +5589,7 @@ EXPORTS
?isClickable@QHeaderView@@QBE_NXZ @ 5588 NONAME ; bool QHeaderView::isClickable(void) const
?isClipEnabled@QPaintEngineState@@QBE_NXZ @ 5589 NONAME ; bool QPaintEngineState::isClipEnabled(void) const
?isClipped@QGraphicsItem@@QBE_NXZ @ 5590 NONAME ; bool QGraphicsItem::isClipped(void) const
- ?isClippedAway@QGraphicsItemPrivate@@QBE_NXZ @ 5591 NONAME ; bool QGraphicsItemPrivate::isClippedAway(void) const
+ ?isClippedAway@QGraphicsItemPrivate@@QBE_NXZ @ 5591 NONAME ABSENT ; bool QGraphicsItemPrivate::isClippedAway(void) const
?isClosed@QPolygonF@@QBE_NXZ @ 5592 NONAME ; bool QPolygonF::isClosed(void) const
?isCollapsible@QSplitter@@QBE_NH@Z @ 5593 NONAME ; bool QSplitter::isCollapsible(int) const
?isColumnHidden@QTableView@@QBE_NH@Z @ 5594 NONAME ; bool QTableView::isColumnHidden(int) const
@@ -8586,7 +8586,7 @@ EXPORTS
?setCacheMode@QGraphicsItem@@QAEXW4CacheMode@1@ABVQSize@@@Z @ 8585 NONAME ; void QGraphicsItem::setCacheMode(enum QGraphicsItem::CacheMode, class QSize const &)
?setCacheMode@QGraphicsView@@QAEXV?$QFlags@W4CacheModeFlag@QGraphicsView@@@@@Z @ 8586 NONAME ; void QGraphicsView::setCacheMode(class QFlags<enum QGraphicsView::CacheModeFlag>)
?setCacheMode@QMovie@@QAEXW4CacheMode@1@@Z @ 8587 NONAME ; void QMovie::setCacheMode(enum QMovie::CacheMode)
- ?setCachedClipPath@QGraphicsItemPrivate@@QAEXABVQPainterPath@@@Z @ 8588 NONAME ; void QGraphicsItemPrivate::setCachedClipPath(class QPainterPath const &)
+ ?setCachedClipPath@QGraphicsItemPrivate@@QAEXABVQPainterPath@@@Z @ 8588 NONAME ABSENT ; void QGraphicsItemPrivate::setCachedClipPath(class QPainterPath const &)
?setCalendarPopup@QDateTimeEdit@@QAEX_N@Z @ 8589 NONAME ; void QDateTimeEdit::setCalendarPopup(bool)
?setCalendarWidget@QDateTimeEdit@@QAEXPAVQCalendarWidget@@@Z @ 8590 NONAME ; void QDateTimeEdit::setCalendarWidget(class QCalendarWidget *)
?setCancelButton@QProgressDialog@@QAEXPAVQPushButton@@@Z @ 8591 NONAME ; void QProgressDialog::setCancelButton(class QPushButton *)
@@ -8901,8 +8901,8 @@ EXPORTS
?setElementPositionAt@QPainterPath@@QAEXHMM@Z @ 8900 NONAME ; void QPainterPath::setElementPositionAt(int, float, float)
?setElideMode@QTabBar@@QAEXW4TextElideMode@Qt@@@Z @ 8901 NONAME ; void QTabBar::setElideMode(enum Qt::TextElideMode)
?setElideMode@QTabWidget@@QAEXW4TextElideMode@Qt@@@Z @ 8902 NONAME ; void QTabWidget::setElideMode(enum Qt::TextElideMode)
- ?setEmptyCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 8903 NONAME ; void QGraphicsItemPrivate::setEmptyCachedClipPath(void)
- ?setEmptyCachedClipPathRecursively@QGraphicsItemPrivate@@QAEXABVQRectF@@@Z @ 8904 NONAME ; void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(class QRectF const &)
+ ?setEmptyCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 8903 NONAME ABSENT ; void QGraphicsItemPrivate::setEmptyCachedClipPath(void)
+ ?setEmptyCachedClipPathRecursively@QGraphicsItemPrivate@@QAEXABVQRectF@@@Z @ 8904 NONAME ABSENT ; void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(class QRectF const &)
?setEmptyLabel@QUndoView@@QAEXABVQString@@@Z @ 8905 NONAME ; void QUndoView::setEmptyLabel(class QString const &)
?setEnabled@QAction@@QAEX_N@Z @ 8906 NONAME ; void QAction::setEnabled(bool)
?setEnabled@QActionGroup@@QAEX_N@Z @ 8907 NONAME ; void QActionGroup::setEnabled(bool)
@@ -9103,7 +9103,7 @@ EXPORTS
?setGestureCancelPolicy@QGesture@@QAEXW4GestureCancelPolicy@1@@Z @ 9102 NONAME ; void QGesture::setGestureCancelPolicy(enum QGesture::GestureCancelPolicy)
?setGlobalStrut@QApplication@@SAXABVQSize@@@Z @ 9103 NONAME ; void QApplication::setGlobalStrut(class QSize const &)
?setGlyphCache@QFontEngine@@QAEXPAXPAVQFontEngineGlyphCache@@@Z @ 9104 NONAME ; void QFontEngine::setGlyphCache(void *, class QFontEngineGlyphCache *)
- ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *)
+ ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ABSENT ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *)
?setGraphicsEffect@QGraphicsItem@@QAEXPAVQGraphicsEffect@@@Z @ 9106 NONAME ; void QGraphicsItem::setGraphicsEffect(class QGraphicsEffect *)
?setGraphicsEffect@QWidget@@QAEXPAVQGraphicsEffect@@@Z @ 9107 NONAME ; void QWidget::setGraphicsEffect(class QGraphicsEffect *)
?setGraphicsEffectSource@QGraphicsEffectPrivate@@QAEXPAVQGraphicsEffectSource@@@Z @ 9108 NONAME ; void QGraphicsEffectPrivate::setGraphicsEffectSource(class QGraphicsEffectSource *)
@@ -11919,7 +11919,7 @@ EXPORTS
?updateBlock@QAbstractTextDocumentLayout@@IAEXABVQTextBlock@@@Z @ 11918 NONAME ; void QAbstractTextDocumentLayout::updateBlock(class QTextBlock const &)
?updateBoundingRect@QGraphicsEffect@@IAEXXZ @ 11919 NONAME ; void QGraphicsEffect::updateBoundingRect(void)
?updateCacheIfNecessary@QWidgetItemV2@@ABEXXZ @ 11920 NONAME ; void QWidgetItemV2::updateCacheIfNecessary(void) const
- ?updateCachedClipPathFromSetPosHelper@QGraphicsItemPrivate@@QAEXABVQPointF@@@Z @ 11921 NONAME ; void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(class QPointF const &)
+ ?updateCachedClipPathFromSetPosHelper@QGraphicsItemPrivate@@QAEXABVQPointF@@@Z @ 11921 NONAME ABSENT ; void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(class QPointF const &)
?updateCell@QCalendarWidget@@IAEXABVQDate@@@Z @ 11922 NONAME ; void QCalendarWidget::updateCell(class QDate const &)
?updateCells@QCalendarWidget@@IAEXXZ @ 11923 NONAME ; void QCalendarWidget::updateCells(void)
?updateDisplayText@QLineControl@@AAEXXZ @ 11924 NONAME ; void QLineControl::updateDisplayText(void)
@@ -12517,4 +12517,12 @@ EXPORTS
?effectiveFocusWidget@QWidgetPrivate@@QAEPAVQWidget@@XZ @ 12516 NONAME ; class QWidget * QWidgetPrivate::effectiveFocusWidget(void)
?ignoreUnusedNavigationEvents@QTextControl@@QBE_NXZ @ 12517 NONAME ; bool QTextControl::ignoreUnusedNavigationEvents(void) const
?setIgnoreUnusedNavigationEvents@QTextControl@@QAEX_N@Z @ 12518 NONAME ; void QTextControl::setIgnoreUnusedNavigationEvents(bool)
+ ??1QImagePixmapCleanupHooks@@QAE@XZ @ 12519 NONAME ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(void)
+ ??1QVectorPath@@QAE@XZ @ 12520 NONAME ; QVectorPath::~QVectorPath(void)
+ ?addCacheData@QVectorPath@@QBEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX01@Z@Z @ 12521 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(class QPaintEngineEx *, void *)) const
+ ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N00@Z @ 12522 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool) const
+ ?makeCacheable@QVectorPath@@QBEXXZ @ 12523 NONAME ; void QVectorPath::makeCacheable(void) const
+ ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ; QTextOption::Tab::Tab(struct QTextOption::Tab const &)
+ ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@ABV2@@Z @ 12525 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QRectF const &) const
+ ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXW4Type@2@ABVQTransform@@@Z @ 12526 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, enum QFontEngineGlyphCache::Type, class QTransform const &) const
diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def
new file mode 100644
index 0000000..88e724f
--- /dev/null
+++ b/src/s60installs/bwins/QtOpenVGu.def
@@ -0,0 +1,142 @@
+EXPORTS
+ ?size@QVGPixmapData@@QBE?AVQSize@@XZ @ 1 NONAME ; class QSize QVGPixmapData::size(void) const
+ ?toVGImage@QVGPixmapData@@UAEKM@Z @ 2 NONAME ; unsigned long QVGPixmapData::toVGImage(float)
+ ?drawEllipse@QVGPaintEngine@@UAEXABVQRect@@@Z @ 3 NONAME ; void QVGPaintEngine::drawEllipse(class QRect const &)
+ ?setState@QVGPaintEngine@@UAEXPAVQPainterState@@@Z @ 4 NONAME ; void QVGPaintEngine::setState(class QPainterState *)
+ ?penChanged@QVGPaintEngine@@UAEXXZ @ 5 NONAME ; void QVGPaintEngine::penChanged(void)
+ ?defaultClipRegion@QVGPaintEngine@@AAE?AVQRegion@@XZ @ 6 NONAME ; class QRegion QVGPaintEngine::defaultClipRegion(void)
+ ??0QVGEGLWindowSurfaceVGImage@@QAE@PAVQWindowSurface@@@Z @ 7 NONAME ; QVGEGLWindowSurfaceVGImage::QVGEGLWindowSurfaceVGImage(class QWindowSurface *)
+ ?paintEngine@QVGPixmapData@@UBEPAVQPaintEngine@@XZ @ 8 NONAME ; class QPaintEngine * QVGPixmapData::paintEngine(void) const
+ ?drawRoundedRect@QVGPaintEngine@@UAEXABVQRectF@@MMW4SizeMode@Qt@@@Z @ 9 NONAME ; void QVGPaintEngine::drawRoundedRect(class QRectF const &, float, float, enum Qt::SizeMode)
+ ?qt_vg_image_to_vg_format@@YA?AW4VGImageFormat@@W4Format@QImage@@@Z @ 10 NONAME ; enum VGImageFormat qt_vg_image_to_vg_format(enum QImage::Format)
+ ?surfaceImage@QVGEGLWindowSurfacePrivate@@UBEKXZ @ 11 NONAME ; unsigned long QVGEGLWindowSurfacePrivate::surfaceImage(void) const
+ ?state@QVGPaintEngine@@QBEPBVQVGPainterState@@XZ @ 12 NONAME ; class QVGPainterState const * QVGPaintEngine::state(void) const
+ ??_EQVGEGLWindowSurfaceDirect@@UAE@I@Z @ 13 NONAME ; QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect(unsigned int)
+ ?updateScissor@QVGPaintEngine@@AAEXXZ @ 14 NONAME ; void QVGPaintEngine::updateScissor(void)
+ ??_EQVGCompositionHelper@@UAE@I@Z @ 15 NONAME ; QVGCompositionHelper::~QVGCompositionHelper(unsigned int)
+ ?fill@QVGPixmapData@@UAEXABVQColor@@@Z @ 16 NONAME ; void QVGPixmapData::fill(class QColor const &)
+ ?toImage@QVGPixmapData@@UBE?AVQImage@@XZ @ 17 NONAME ; class QImage QVGPixmapData::toImage(void) const
+ ?renderHintsChanged@QVGPaintEngine@@UAEXXZ @ 18 NONAME ; void QVGPaintEngine::renderHintsChanged(void)
+ ?clearRect@QVGPaintEngine@@AAE_NABVQRectF@@ABVQColor@@@Z @ 19 NONAME ; bool QVGPaintEngine::clearRect(class QRectF const &, class QColor const &)
+ ??1QVGEGLWindowSurfaceVGImage@@UAE@XZ @ 20 NONAME ; QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage(void)
+ ?state@QVGPaintEngine@@QAEPAVQVGPainterState@@XZ @ 21 NONAME ; class QVGPainterState * QVGPaintEngine::state(void)
+ ??0QVGPaintEngine@@IAE@AAVQVGPaintEnginePrivate@@@Z @ 22 NONAME ; QVGPaintEngine::QVGPaintEngine(class QVGPaintEnginePrivate &)
+ ?blitWindow@QVGCompositionHelper@@QAEXKABVQSize@@ABVQRect@@ABVQPoint@@H@Z @ 23 NONAME ; void QVGCompositionHelper::blitWindow(unsigned long, class QSize const &, class QRect const &, class QPoint const &, int)
+ ?ensureContext@QVGEGLWindowSurfaceVGImage@@UAEPAVQEglContext@@PAVQWidget@@@Z @ 24 NONAME ; class QEglContext * QVGEGLWindowSurfaceVGImage::ensureContext(class QWidget *)
+ ??0QVGCompositionHelper@@QAE@XZ @ 25 NONAME ; QVGCompositionHelper::QVGCompositionHelper(void)
+ ?sourceFormat@QVGPixmapData@@IBE?AW4Format@QImage@@XZ @ 26 NONAME ; enum QImage::Format QVGPixmapData::sourceFormat(void) const
+ ?beginNativePainting@QVGPaintEngine@@UAEXXZ @ 27 NONAME ; void QVGPaintEngine::beginNativePainting(void)
+ ?clipEnabledChanged@QVGPaintEngine@@UAEXXZ @ 28 NONAME ; void QVGPaintEngine::clipEnabledChanged(void)
+ ?metric@QVGPixmapData@@MBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 29 NONAME ; int QVGPixmapData::metric(enum QPaintDevice::PaintDeviceMetric) const
+ ?draw@QVGPaintEngine@@UAEXABVQVectorPath@@@Z @ 30 NONAME ; void QVGPaintEngine::draw(class QVectorPath const &)
+ ?drawRects@QVGPaintEngine@@UAEXPBVQRect@@H@Z @ 31 NONAME ; void QVGPaintEngine::drawRects(class QRect const *, int)
+ ??0QVGPixmapData@@QAE@W4PixelType@QPixmapData@@@Z @ 32 NONAME ; QVGPixmapData::QVGPixmapData(enum QPixmapData::PixelType)
+ ??0QVGWindowSurface@@QAE@PAVQWidget@@PAVQVGEGLWindowSurfacePrivate@@@Z @ 33 NONAME ; QVGWindowSurface::QVGWindowSurface(class QWidget *, class QVGEGLWindowSurfacePrivate *)
+ ?fillBackground@QVGCompositionHelper@@QAEXABVQRegion@@ABVQBrush@@@Z @ 34 NONAME ; void QVGCompositionHelper::fillBackground(class QRegion const &, class QBrush const &)
+ ?drawLines@QVGPaintEngine@@UAEXPBVQLine@@H@Z @ 35 NONAME ; void QVGPaintEngine::drawLines(class QLine const *, int)
+ ?ensureContext@QVGEGLWindowSurfaceDirect@@UAEPAVQEglContext@@PAVQWidget@@@Z @ 36 NONAME ; class QEglContext * QVGEGLWindowSurfaceDirect::ensureContext(class QWidget *)
+ ??0QVGPaintEngine@@QAE@XZ @ 37 NONAME ; QVGPaintEngine::QVGPaintEngine(void)
+ ?cleanup@QVGPixmapData@@IAEXXZ @ 38 NONAME ; void QVGPixmapData::cleanup(void)
+ ?drawPixmap@QVGPaintEngine@@UAEXABVQPointF@@ABVQPixmap@@@Z @ 39 NONAME ; void QVGPaintEngine::drawPixmap(class QPointF const &, class QPixmap const &)
+ ?drawImage@QVGPaintEngine@@UAEXABVQRectF@@ABVQImage@@0V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 40 NONAME ; void QVGPaintEngine::drawImage(class QRectF const &, class QImage const &, class QRectF const &, class QFlags<enum Qt::ImageConversionFlag>)
+ ?drawTiledPixmap@QVGPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@ABVQPointF@@@Z @ 41 NONAME ; void QVGPaintEngine::drawTiledPixmap(class QRectF const &, class QPixmap const &, class QPointF const &)
+ ?drawEllipse@QVGPaintEngine@@UAEXABVQRectF@@@Z @ 42 NONAME ; void QVGPaintEngine::drawEllipse(class QRectF const &)
+ ?endCompositing@QVGCompositionHelper@@QAEXXZ @ 43 NONAME ; void QVGCompositionHelper::endCompositing(void)
+ ??_EQVGEGLWindowSurfaceVGImage@@UAE@I@Z @ 44 NONAME ; QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage(unsigned int)
+ ?begin@QVGPaintEngine@@UAE_NPAVQPaintDevice@@@Z @ 45 NONAME ; bool QVGPaintEngine::begin(class QPaintDevice *)
+ ?fillRect@QVGPaintEngine@@UAEXABVQRectF@@ABVQBrush@@@Z @ 46 NONAME ; void QVGPaintEngine::fillRect(class QRectF const &, class QBrush const &)
+ ?paintEngine@QVGWindowSurface@@UBEPAVQPaintEngine@@XZ @ 47 NONAME ; class QPaintEngine * QVGWindowSurface::paintEngine(void) const
+ ??0QVGPainterState@@QAE@XZ @ 48 NONAME ; QVGPainterState::QVGPainterState(void)
+ ?d_func@QVGPaintEngine@@ABEPBVQVGPaintEnginePrivate@@XZ @ 49 NONAME ; class QVGPaintEnginePrivate const * QVGPaintEngine::d_func(void) const
+ ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *)
+ ?clip@QVGPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 51 NONAME ; void QVGPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation)
+ ?endNativePainting@QVGPaintEngine@@UAEXXZ @ 52 NONAME ; void QVGPaintEngine::endNativePainting(void)
+ ?brushChanged@QVGPaintEngine@@UAEXXZ @ 53 NONAME ; void QVGPaintEngine::brushChanged(void)
+ ?setGeometry@QVGWindowSurface@@UAEXABVQRect@@@Z @ 54 NONAME ; void QVGWindowSurface::setGeometry(class QRect const &)
+ ?createCompatiblePixmapData@QVGPixmapData@@UBEPAVQPixmapData@@XZ @ 55 NONAME ; class QPixmapData * QVGPixmapData::createCompatiblePixmapData(void) const
+ ?endPaint@QVGWindowSurface@@UAEXABVQRegion@@@Z @ 56 NONAME ; void QVGWindowSurface::endPaint(class QRegion const &)
+ ?resize@QVGPixmapData@@UAEXHH@Z @ 57 NONAME ; void QVGPixmapData::resize(int, int)
+ ?mainSurface@QVGEGLWindowSurfaceVGImage@@IBEHXZ @ 58 NONAME ; int QVGEGLWindowSurfaceVGImage::mainSurface(void) const
+ ??0QVGEGLWindowSurfaceDirect@@QAE@PAVQWindowSurface@@@Z @ 59 NONAME ; QVGEGLWindowSurfaceDirect::QVGEGLWindowSurfaceDirect(class QWindowSurface *)
+ ?clip@QVGPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 60 NONAME ; void QVGPaintEngine::clip(class QRect const &, enum Qt::ClipOperation)
+ ?fillRegion@QVGPaintEngine@@QAEXABVQRegion@@ABVQColor@@ABVQSize@@@Z @ 61 NONAME ; void QVGPaintEngine::fillRegion(class QRegion const &, class QColor const &, class QSize const &)
+ ?surfaceSize@QVGEGLWindowSurfaceDirect@@UBE?AVQSize@@XZ @ 62 NONAME ; class QSize QVGEGLWindowSurfaceDirect::surfaceSize(void) const
+ ?drawPoints@QVGPaintEngine@@UAEXPBVQPointF@@H@Z @ 63 NONAME ; void QVGPaintEngine::drawPoints(class QPointF const *, int)
+ ?paintEngine@QVGEGLWindowSurfacePrivate@@QAEPAVQVGPaintEngine@@XZ @ 64 NONAME ; class QVGPaintEngine * QVGEGLWindowSurfacePrivate::paintEngine(void)
+ ?stroke@QVGPaintEngine@@UAEXABVQVectorPath@@ABVQPen@@@Z @ 65 NONAME ; void QVGPaintEngine::stroke(class QVectorPath const &, class QPen const &)
+ ??0QVGPainterState@@QAE@AAV0@@Z @ 66 NONAME ; QVGPainterState::QVGPainterState(class QVGPainterState &)
+ ?startCompositing@QVGCompositionHelper@@QAEXABVQSize@@@Z @ 67 NONAME ; void QVGCompositionHelper::startCompositing(class QSize const &)
+ ??1QVGEGLWindowSurfacePrivate@@UAE@XZ @ 68 NONAME ; QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate(void)
+ ?qt_vg_destroy_paint_engine@@YAXPAVQVGPaintEngine@@@Z @ 69 NONAME ; void qt_vg_destroy_paint_engine(class QVGPaintEngine *)
+ ?compositionModeChanged@QVGPaintEngine@@UAEXXZ @ 70 NONAME ; void QVGPaintEngine::compositionModeChanged(void)
+ ?type@QVGPaintEngine@@UBE?AW4Type@QPaintEngine@@XZ @ 71 NONAME ; enum QPaintEngine::Type QVGPaintEngine::type(void) const
+ ?fillRect@QVGPaintEngine@@UAEXABVQRectF@@ABVQColor@@@Z @ 72 NONAME ; void QVGPaintEngine::fillRect(class QRectF const &, class QColor const &)
+ ??0QVGEGLWindowSurfacePrivate@@QAE@PAVQWindowSurface@@@Z @ 73 NONAME ; QVGEGLWindowSurfacePrivate::QVGEGLWindowSurfacePrivate(class QWindowSurface *)
+ ?drawImage@QVGPaintEngine@@UAEXABVQPointF@@ABVQImage@@@Z @ 74 NONAME ; void QVGPaintEngine::drawImage(class QPointF const &, class QImage const &)
+ ?flush@QVGWindowSurface@@UAEXPAVQWidget@@ABVQRegion@@ABVQPoint@@@Z @ 75 NONAME ; void QVGWindowSurface::flush(class QWidget *, class QRegion const &, class QPoint const &)
+ ?isValid@QVGPixmapData@@QBE_NXZ @ 76 NONAME ; bool QVGPixmapData::isValid(void) const
+ ?beginPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@@Z @ 77 NONAME ; void QVGEGLWindowSurfaceVGImage::beginPaint(class QWidget *)
+ ?createState@QVGPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 78 NONAME ; class QPainterState * QVGPaintEngine::createState(class QPainterState *) const
+ ?buffer@QVGPixmapData@@UAEPAVQImage@@XZ @ 79 NONAME ; class QImage * QVGPixmapData::buffer(void)
+ ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ; void qt_vg_destroy_context(class QEglContext *)
+ ?clip@QVGPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 81 NONAME ; void QVGPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation)
+ ?drawPolygon@QVGPaintEngine@@UAEXPBVQPoint@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 82 NONAME ; void QVGPaintEngine::drawPolygon(class QPoint const *, int, enum QPaintEngine::PolygonDrawMode)
+ ?fromImage@QVGPixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 83 NONAME ; void QVGPixmapData::fromImage(class QImage const &, class QFlags<enum Qt::ImageConversionFlag>)
+ ??1QVGPainterState@@UAE@XZ @ 84 NONAME ; QVGPainterState::~QVGPainterState(void)
+ ??1QVGPaintEngine@@UAE@XZ @ 85 NONAME ; QVGPaintEngine::~QVGPaintEngine(void)
+ ?hasAlphaChannel@QVGPixmapData@@UBE_NXZ @ 86 NONAME ; bool QVGPixmapData::hasAlphaChannel(void) const
+ ?endPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@ABVQRegion@@PAVQImage@@@Z @ 87 NONAME ; void QVGEGLWindowSurfaceVGImage::endPaint(class QWidget *, class QRegion const &, class QImage *)
+ ?beginPaint@QVGEGLWindowSurfaceDirect@@UAEXPAVQWidget@@@Z @ 88 NONAME ; void QVGEGLWindowSurfaceDirect::beginPaint(class QWidget *)
+ ?qt_vg_config_to_image_format@@YA?AW4Format@QImage@@PAVQEglContext@@@Z @ 89 NONAME ; enum QImage::Format qt_vg_config_to_image_format(class QEglContext *)
+ ?qt_vg_config_to_vg_format@@YA?AW4VGImageFormat@@PAVQEglContext@@@Z @ 90 NONAME ; enum VGImageFormat qt_vg_config_to_vg_format(class QEglContext *)
+ ?setScissor@QVGCompositionHelper@@QAEXABVQRegion@@@Z @ 91 NONAME ; void QVGCompositionHelper::setScissor(class QRegion const &)
+ ?drawPath@QVGPaintEngine@@UAEXABVQPainterPath@@@Z @ 92 NONAME ; void QVGPaintEngine::drawPath(class QPainterPath const &)
+ ?drawLines@QVGPaintEngine@@UAEXPBVQLineF@@H@Z @ 93 NONAME ; void QVGPaintEngine::drawLines(class QLineF const *, int)
+ ?toNativeType@QVGPixmapData@@UAEPAXW4NativeType@QPixmapData@@@Z @ 94 NONAME ; void * QVGPixmapData::toNativeType(enum QPixmapData::NativeType)
+ ??1QVGWindowSurface@@UAE@XZ @ 95 NONAME ; QVGWindowSurface::~QVGWindowSurface(void)
+ ?metric@QVGWindowSurface@@MBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 96 NONAME ; int QVGWindowSurface::metric(enum QPaintDevice::PaintDeviceMetric) const
+ ??1QVGPixmapData@@UAE@XZ @ 97 NONAME ; QVGPixmapData::~QVGPixmapData(void)
+ ??1QVGEGLWindowSurfaceDirect@@UAE@XZ @ 98 NONAME ; QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect(void)
+ ??_EQVGPixmapData@@UAE@I@Z @ 99 NONAME ; QVGPixmapData::~QVGPixmapData(unsigned int)
+ ?restoreState@QVGPaintEngine@@AAEXV?$QFlags@W4DirtyFlag@QPaintEngine@@@@@Z @ 100 NONAME ; void QVGPaintEngine::restoreState(class QFlags<enum QPaintEngine::DirtyFlag>)
+ ??1QVGCompositionHelper@@UAE@XZ @ 101 NONAME ; QVGCompositionHelper::~QVGCompositionHelper(void)
+ ??0QVGWindowSurface@@QAE@PAVQWidget@@@Z @ 102 NONAME ; QVGWindowSurface::QVGWindowSurface(class QWidget *)
+ ?isDefaultClipRegion@QVGPaintEngine@@AAE_NABVQRegion@@@Z @ 103 NONAME ; bool QVGPaintEngine::isDefaultClipRegion(class QRegion const &)
+ ?transformChanged@QVGPaintEngine@@UAEXXZ @ 104 NONAME ; void QVGPaintEngine::transformChanged(void)
+ ?fromNativeType@QVGPixmapData@@UAEXPAXW4NativeType@QPixmapData@@@Z @ 105 NONAME ; void QVGPixmapData::fromNativeType(void *, enum QPixmapData::NativeType)
+ ?setAlphaChannel@QVGPixmapData@@UAEXABVQPixmap@@@Z @ 106 NONAME ; void QVGPixmapData::setAlphaChannel(class QPixmap const &)
+ ??_EQVGWindowSurface@@UAE@I@Z @ 107 NONAME ; QVGWindowSurface::~QVGWindowSurface(unsigned int)
+ ?qPixmapToVGImage@@YAKABVQPixmap@@@Z @ 108 NONAME ; unsigned long qPixmapToVGImage(class QPixmap const &)
+ ?opacityChanged@QVGPaintEngine@@UAEXXZ @ 109 NONAME ; void QVGPaintEngine::opacityChanged(void)
+ ?surfaceSize@QVGEGLWindowSurfaceVGImage@@UBE?AVQSize@@XZ @ 110 NONAME ; class QSize QVGEGLWindowSurfaceVGImage::surfaceSize(void) const
+ ?paintDevice@QVGWindowSurface@@UAEPAVQPaintDevice@@XZ @ 111 NONAME ; class QPaintDevice * QVGWindowSurface::paintDevice(void)
+ ?qt_vg_create_paint_engine@@YAPAVQVGPaintEngine@@XZ @ 112 NONAME ; class QVGPaintEngine * qt_vg_create_paint_engine(void)
+ ?drawPixmap@QVGPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@0@Z @ 113 NONAME ; void QVGPaintEngine::drawPixmap(class QRectF const &, class QPixmap const &, class QRectF const &)
+ ?beginPaint@QVGWindowSurface@@UAEXABVQRegion@@@Z @ 114 NONAME ; void QVGWindowSurface::beginPaint(class QRegion const &)
+ ??_EQVGEGLWindowSurfacePrivate@@UAE@I@Z @ 115 NONAME ; QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate(unsigned int)
+ ?endPaint@QVGEGLWindowSurfaceDirect@@UAEXPAVQWidget@@ABVQRegion@@PAVQImage@@@Z @ 116 NONAME ; void QVGEGLWindowSurfaceDirect::endPaint(class QWidget *, class QRegion const &, class QImage *)
+ ?scroll@QVGWindowSurface@@UAE_NABVQRegion@@HH@Z @ 117 NONAME ; bool QVGWindowSurface::scroll(class QRegion const &, int, int)
+ ?surfaceImage@QVGEGLWindowSurfaceVGImage@@UBEKXZ @ 118 NONAME ; unsigned long QVGEGLWindowSurfaceVGImage::surfaceImage(void) const
+ ?isDefaultClipRect@QVGPaintEngine@@AAE_NABVQRect@@@Z @ 119 NONAME ; bool QVGPaintEngine::isDefaultClipRect(class QRect const &)
+ ?windowSurfaceSize@QVGEGLWindowSurfacePrivate@@IBE?AVQSize@@PAVQWidget@@@Z @ 120 NONAME ; class QSize QVGEGLWindowSurfacePrivate::windowSurfaceSize(class QWidget *) const
+ ?pixmapFilter@QVGPaintEngine@@UAEPAVQPixmapFilter@@HPBV2@@Z @ 121 NONAME ; class QPixmapFilter * QVGPaintEngine::pixmapFilter(int, class QPixmapFilter const *)
+ ?destroyPaintEngine@QVGEGLWindowSurfacePrivate@@IAEXXZ @ 122 NONAME ; void QVGEGLWindowSurfacePrivate::destroyPaintEngine(void)
+ ?qt_vg_shared_surface@@YAHXZ @ 123 NONAME ; int qt_vg_shared_surface(void)
+ ?drawCursorPixmap@QVGCompositionHelper@@QAEXABVQPixmap@@ABVQPoint@@@Z @ 124 NONAME ; void QVGCompositionHelper::drawCursorPixmap(class QPixmap const &, class QPoint const &)
+ ?drawPixmaps@QVGPaintEngine@@UAEXPBUData@QDrawPixmaps@@HABVQPixmap@@V?$QFlags@W4DrawingHint@QDrawPixmaps@@@@@Z @ 125 NONAME ; void QVGPaintEngine::drawPixmaps(struct QDrawPixmaps::Data const *, int, class QPixmap const &, class QFlags<enum QDrawPixmaps::DrawingHint>)
+ ?drawPolygon@QVGPaintEngine@@UAEXPBVQPointF@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 126 NONAME ; void QVGPaintEngine::drawPolygon(class QPointF const *, int, enum QPaintEngine::PolygonDrawMode)
+ ?toVGImage@QVGPixmapData@@UAEKXZ @ 127 NONAME ; unsigned long QVGPixmapData::toVGImage(void)
+ ?end@QVGPaintEngine@@UAE_NXZ @ 128 NONAME ; bool QVGPaintEngine::end(void)
+ ??_EQVGPainterState@@UAE@I@Z @ 129 NONAME ; QVGPainterState::~QVGPainterState(unsigned int)
+ ?drawRects@QVGPaintEngine@@UAEXPBVQRectF@@H@Z @ 130 NONAME ; void QVGPaintEngine::drawRects(class QRectF const *, int)
+ ?d_func@QVGPaintEngine@@AAEPAVQVGPaintEnginePrivate@@XZ @ 131 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::d_func(void)
+ ?brushOriginChanged@QVGPaintEngine@@UAEXXZ @ 132 NONAME ; void QVGPaintEngine::brushOriginChanged(void)
+ ?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)
+ ?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)
+ ?vgPrivate@QVGPaintEngine@@QAEPAVQVGPaintEnginePrivate@@XZ @ 140 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::vgPrivate(void)
+
diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def
index 6a4cdbd..89fa76f 100644
--- a/src/s60installs/eabi/QtCoreu.def
+++ b/src/s60installs/eabi/QtCoreu.def
@@ -2556,7 +2556,7 @@ EXPORTS
_ZNK14QObjectPrivate10senderListEv @ 2555 NONAME
_ZNK14QObjectPrivate11signalIndexEPKc @ 2556 NONAME
_ZNK14QObjectPrivate12receiverListEPKc @ 2557 NONAME
- _ZNK14QObjectPrivate17isSignalConnectedEi @ 2558 NONAME
+ _ZNK14QObjectPrivate17isSignalConnectedEi @ 2558 NONAME ABSENT
_ZNK14QObjectPrivate8isSenderEPK7QObjectPKc @ 2559 NONAME
_ZNK14QStringMatcher7indexInEPK5QCharii @ 2560 NONAME
_ZNK14QStringMatcher7indexInERK7QStringi @ 2561 NONAME
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 6c45a6e..b6862e5 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -698,13 +698,13 @@ EXPORTS
_ZN11QFontDialogD2Ev @ 697 NONAME
_ZN11QFontEngine11boundingBoxEjRK10QTransform @ 698 NONAME
_ZN11QFontEngine11grayPaletteEv @ 699 NONAME
- _ZN11QFontEngine13setGlyphCacheEN21QFontEngineGlyphCache4TypeEPS0_ @ 700 NONAME
+ _ZN11QFontEngine13setGlyphCacheEN21QFontEngineGlyphCache4TypeEPS0_ @ 700 NONAME ABSENT
_ZN11QFontEngine13setGlyphCacheEPvP21QFontEngineGlyphCache @ 701 NONAME
_ZN11QFontEngine15addGlyphsToPathEPjP11QFixedPointiP12QPainterPath6QFlagsIN9QTextItem10RenderFlagEE @ 702 NONAME
_ZN11QFontEngine16addOutlineToPathEffRK12QGlyphLayoutP12QPainterPath6QFlagsIN9QTextItem10RenderFlagEE @ 703 NONAME
_ZN11QFontEngine16alphaMapForGlyphEj @ 704 NONAME
_ZN11QFontEngine16alphaMapForGlyphEjRK10QTransform @ 705 NONAME
- _ZN11QFontEngine16expireGlyphCacheEv @ 706 NONAME
+ _ZN11QFontEngine16expireGlyphCacheEv @ 706 NONAME ABSENT
_ZN11QFontEngine16getUnscaledGlyphEjP12QPainterPathP15glyph_metrics_t @ 707 NONAME
_ZN11QFontEngine16loadKerningPairsE6QFixed @ 708 NONAME
_ZN11QFontEngine16tightBoundingBoxERK12QGlyphLayout @ 709 NONAME
@@ -4680,9 +4680,9 @@ EXPORTS
_ZN20QGraphicsItemPrivate28ensureSequentialSiblingIndexEv @ 4679 NONAME
_ZN20QGraphicsItemPrivate29ensureSceneTransformRecursiveEPP13QGraphicsItem @ 4680 NONAME
_ZN20QGraphicsItemPrivate30updateSceneTransformFromParentEv @ 4681 NONAME
- _ZN20QGraphicsItemPrivate33setEmptyCachedClipPathRecursivelyERK6QRectF @ 4682 NONAME
- _ZN20QGraphicsItemPrivate35invalidateCachedClipPathRecursivelyEbRK6QRectF @ 4683 NONAME
- _ZN20QGraphicsItemPrivate36updateCachedClipPathFromSetPosHelperERK7QPointF @ 4684 NONAME
+ _ZN20QGraphicsItemPrivate33setEmptyCachedClipPathRecursivelyERK6QRectF @ 4682 NONAME ABSENT
+ _ZN20QGraphicsItemPrivate35invalidateCachedClipPathRecursivelyEbRK6QRectF @ 4683 NONAME ABSENT
+ _ZN20QGraphicsItemPrivate36updateCachedClipPathFromSetPosHelperERK7QPointF @ 4684 NONAME ABSENT
_ZN20QGraphicsItemPrivate8addChildEP13QGraphicsItem @ 4685 NONAME
_ZN20QGraphicsPolygonItem10setPolygonERK9QPolygonF @ 4686 NONAME
_ZN20QGraphicsPolygonItem11setFillRuleEN2Qt8FillRuleE @ 4687 NONAME
@@ -5221,8 +5221,8 @@ EXPORTS
_ZN24QImagePixmapCleanupHooks17executeImageHooksEx @ 5220 NONAME
_ZN24QImagePixmapCleanupHooks18executePixmapHooksEP7QPixmap @ 5221 NONAME ABSENT
_ZN24QImagePixmapCleanupHooks8instanceEv @ 5222 NONAME
- _ZN24QImagePixmapCleanupHooksC1Ev @ 5223 NONAME
- _ZN24QImagePixmapCleanupHooksC2Ev @ 5224 NONAME
+ _ZN24QImagePixmapCleanupHooksC1Ev @ 5223 NONAME ABSENT
+ _ZN24QImagePixmapCleanupHooksC2Ev @ 5224 NONAME ABSENT
_ZN24QPixmapConvolutionFilter11qt_metacallEN11QMetaObject4CallEiPPv @ 5225 NONAME
_ZN24QPixmapConvolutionFilter11qt_metacastEPKc @ 5226 NONAME
_ZN24QPixmapConvolutionFilter16staticMetaObjectE @ 5227 NONAME DATA 16
@@ -7615,8 +7615,8 @@ EXPORTS
_ZNK11QFontDialog11currentFontEv @ 7614 NONAME
_ZNK11QFontDialog12selectedFontEv @ 7615 NONAME
_ZNK11QFontDialog7optionsEv @ 7616 NONAME
- _ZNK11QFontEngine10glyphCacheEN21QFontEngineGlyphCache4TypeERK10QTransform @ 7617 NONAME
- _ZNK11QFontEngine10glyphCacheEPvRK10QTransform @ 7618 NONAME
+ _ZNK11QFontEngine10glyphCacheEN21QFontEngineGlyphCache4TypeERK10QTransform @ 7617 NONAME ABSENT
+ _ZNK11QFontEngine10glyphCacheEPvRK10QTransform @ 7618 NONAME ABSENT
_ZNK11QFontEngine10glyphCountEv @ 7619 NONAME
_ZNK11QFontEngine10propertiesEv @ 7620 NONAME
_ZNK11QFontEngine12getSfntTableEj @ 7621 NONAME
@@ -9388,7 +9388,7 @@ EXPORTS
_ZNK20QGraphicsItemPrivate15initStyleOptionEP24QStyleOptionGraphicsItemRK10QTransformRK7QRegionb @ 9387 NONAME
_ZNK20QGraphicsItemPrivate19genericMapFromSceneERK7QPointFPK7QWidget @ 9388 NONAME
_ZNK20QGraphicsItemPrivate19maybeExtraItemCacheEv @ 9389 NONAME
- _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbbb @ 9390 NONAME
+ _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbbb @ 9390 NONAME ABSENT
_ZNK20QGraphicsItemPrivate21effectiveBoundingRectEv @ 9391 NONAME
_ZNK20QGraphicsItemPrivate22inputMethodQueryHelperEN2Qt16InputMethodQueryE @ 9392 NONAME
_ZNK20QGraphicsItemPrivate24combineTransformToParentEP10QTransformPKS0_ @ 9393 NONAME
@@ -11571,7 +11571,7 @@ EXPORTS
_ZN11QTapGesture19getStaticMetaObjectEv @ 11570 NONAME
_ZN11QTapGestureC1EP7QObject @ 11571 NONAME
_ZN11QTapGestureC2EP7QObject @ 11572 NONAME
- _ZN11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS2_E @ 11573 NONAME
+ _ZN11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS2_E @ 11573 NONAME ABSENT
_ZN12QApplication18symbianEventFilterEPK13QSymbianEvent @ 11574 NONAME
_ZN12QApplication19symbianProcessEventEPK13QSymbianEvent @ 11575 NONAME
_ZN13QGestureEvent11setAcceptedEN2Qt11GestureTypeEb @ 11576 NONAME
@@ -11737,4 +11737,51 @@ EXPORTS
_Zls6QDebugRKN12QStyleOption10OptionTypeE @ 11736 NONAME
_ZN12QTextControl31setIgnoreUnusedNavigationEventsEb @ 11737 NONAME
_ZNK12QTextControl28ignoreUnusedNavigationEventsEv @ 11738 NONAME
+ _ZN11QVectorPathD1Ev @ 11739 NONAME
+ _ZN11QVectorPathD2Ev @ 11740 NONAME
+ _ZNK11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS1_S2_E @ 11741 NONAME
+ _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbb @ 11742 NONAME
+ _ZN11QEglContext10extensionsEv @ 11743 NONAME ABSENT
+ _ZN11QEglContext10getDisplayEP12QPaintDevice @ 11744 NONAME ABSENT
+ _ZN11QEglContext10waitClientEv @ 11745 NONAME ABSENT
+ _ZN11QEglContext10waitNativeEv @ 11746 NONAME ABSENT
+ _ZN11QEglContext11doneCurrentEv @ 11747 NONAME ABSENT
+ _ZN11QEglContext11errorStringEi @ 11748 NONAME ABSENT
+ _ZN11QEglContext11makeCurrentEi @ 11749 NONAME ABSENT
+ _ZN11QEglContext11openDisplayEP12QPaintDevice @ 11750 NONAME ABSENT
+ _ZN11QEglContext11swapBuffersEi @ 11751 NONAME ABSENT
+ _ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME ABSENT
+ _ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME ABSENT
+ _ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME ABSENT
+ _ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME ABSENT
+ _ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME ABSENT
+ _ZN11QEglContext14defaultDisplayEP12QPaintDevice @ 11757 NONAME ABSENT
+ _ZN11QEglContext14destroySurfaceEi @ 11758 NONAME ABSENT
+ _ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME ABSENT
+ _ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME ABSENT
+ _ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME ABSENT
+ _ZN11QEglContext7destroyEv @ 11762 NONAME ABSENT
+ _ZN11QEglContextC1Ev @ 11763 NONAME ABSENT
+ _ZN11QEglContextC2Ev @ 11764 NONAME ABSENT
+ _ZN11QEglContextD1Ev @ 11765 NONAME ABSENT
+ _ZN11QEglContextD2Ev @ 11766 NONAME ABSENT
+ _ZN14QEglProperties11removeValueEi @ 11767 NONAME ABSENT
+ _ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME ABSENT
+ _ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME ABSENT
+ _ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME ABSENT
+ _ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME ABSENT
+ _ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME ABSENT
+ _ZN14QEglProperties8setValueEii @ 11773 NONAME ABSENT
+ _ZN14QEglPropertiesC1Ei @ 11774 NONAME ABSENT
+ _ZN14QEglPropertiesC1Ev @ 11775 NONAME ABSENT
+ _ZN14QEglPropertiesC2Ei @ 11776 NONAME ABSENT
+ _ZN14QEglPropertiesC2Ev @ 11777 NONAME ABSENT
+ _ZNK11QEglContext12configAttribEiPi @ 11778 NONAME ABSENT
+ _ZNK11QEglContext16configPropertiesEi @ 11779 NONAME ABSENT
+ _ZNK11QEglContext7isValidEv @ 11780 NONAME ABSENT
+ _ZNK11QEglContext9isCurrentEv @ 11781 NONAME ABSENT
+ _ZNK14QEglProperties5valueEi @ 11782 NONAME ABSENT
+ _ZNK14QEglProperties8toStringEv @ 11783 NONAME ABSENT
+ _ZNK11QFontEngine10glyphCacheEPvN21QFontEngineGlyphCache4TypeERK10QTransform @ 11784 NONAME
+ _ZNK20QGraphicsItemPrivate21effectiveBoundingRectERK6QRectF @ 11785 NONAME
diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def
index 776fc4b..7526632 100644
--- a/src/s60installs/eabi/QtOpenVGu.def
+++ b/src/s60installs/eabi/QtOpenVGu.def
@@ -1,8 +1,8 @@
EXPORTS
_Z16qPixmapToVGImageRK7QPixmap @ 1 NONAME
- _Z20qt_vg_create_contextP12QPaintDevice @ 2 NONAME
+ _Z20qt_vg_create_contextP12QPaintDevice @ 2 NONAME ABSENT
_Z20qt_vg_shared_surfacev @ 3 NONAME
- _Z21qt_vg_destroy_contextP11QEglContext @ 4 NONAME
+ _Z21qt_vg_destroy_contextP11QEglContext @ 4 NONAME ABSENT
_Z24qt_vg_image_to_vg_formatN6QImage6FormatE @ 5 NONAME
_Z25qt_vg_config_to_vg_formatP11QEglContext @ 6 NONAME
_Z25qt_vg_create_paint_enginev @ 7 NONAME
@@ -99,7 +99,7 @@ EXPORTS
_ZN16QVGWindowSurfaceD0Ev @ 98 NONAME
_ZN16QVGWindowSurfaceD1Ev @ 99 NONAME
_ZN16QVGWindowSurfaceD2Ev @ 100 NONAME
- _ZN20QVGCompositionHelper10blitWindowEP26QVGEGLWindowSurfacePrivateRK5QRectRK6QPointi @ 101 NONAME
+ _ZN20QVGCompositionHelper10blitWindowEP26QVGEGLWindowSurfacePrivateRK5QRectRK6QPointi @ 101 NONAME ABSENT
_ZN20QVGCompositionHelper10setScissorERK7QRegion @ 102 NONAME
_ZN20QVGCompositionHelper12clearScissorEv @ 103 NONAME
_ZN20QVGCompositionHelper14endCompositingEv @ 104 NONAME
@@ -167,4 +167,10 @@ EXPORTS
_ZThn8_N16QVGWindowSurfaceD1Ev @ 166 NONAME
_ZThn8_NK16QVGWindowSurface11paintEngineEv @ 167 NONAME
_ZThn8_NK16QVGWindowSurface6metricEN12QPaintDevice17PaintDeviceMetricE @ 168 NONAME
+ _ZN14QVGPaintEngine10fillRegionERK7QRegionRK6QColorRK5QSize @ 169 NONAME
+ _ZN20QVGCompositionHelper10blitWindowEmRK5QSizeRK5QRectRK6QPointi @ 170 NONAME
+ _Z20qt_vg_create_contextP12QPaintDevicei @ 171 NONAME
+ _Z21qt_vg_destroy_contextP11QEglContexti @ 172 NONAME
+ _ZN13QVGPixmapData22destroyImageAndContextEv @ 173 NONAME
+ _ZN13QVGPixmapData9hibernateEv @ 174 NONAME
diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby
index 41eb562..f24ac4b 100644
--- a/src/s60installs/qt.iby
+++ b/src/s60installs/qt.iby
@@ -90,27 +90,27 @@ file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll
S60_APP_RESOURCE(s60main)
// imageformats stubs
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin
// codecs stubs
-data=\epoc32\winscw\c\resource\qt\plugins\codecs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\codecs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\codecs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin
-data=\epoc32\winscw\c\resource\qt\plugins\codecs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin
// iconengines stubs
-data=\epoc32\winscw\c\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin
// Phonon MMF backend
-data=\epoc32\winscw\c\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin
// graphicssystems
-data=\epoc32\winscw\c\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin
+data=\epoc32\data\qt\qtlibspluginstubs\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin
// Stub sis file
data=ZSYSTEM\install\qt.sis System\Install\qt.sis
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 37adfa9..e024396 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -105,10 +105,6 @@ symbian: {
qtlibraries.sources += QtDeclarative.dll
}
- contains(QT_CONFIG, webkit): {
- qtlibraries.sources += QtWebKit.dll
- }
-
graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems
contains(QT_CONFIG, openvg) {
qtlibraries.sources += QtOpenVG.dll
@@ -117,4 +113,9 @@ symbian: {
BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)"
BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CORE_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)"
+ PLUGIN_STUBS = $$files(qmakepluginstubs/*)
+ for(STUB, PLUGIN_STUBS) {
+ STUB_FILENAME = $$basename(STUB)
+ BLD_INF_RULES.prj_exports += "qmakepluginstubs/$${STUB_FILENAME} /epoc32/data/qt/qtlibspluginstubs/$${STUB_FILENAME}"
+ }
}
diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp
index 725b17c..8923fb9 100644
--- a/src/s60main/qts60main.cpp
+++ b/src/s60main/qts60main.cpp
@@ -6,35 +6,33 @@
**
** This file is part of the Symbian application wrapper 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_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -54,7 +52,7 @@ GLDEF_C TInt E32Main()
{
CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New());
TInt err = 0;
- TRAP(err, QtMainWrapper());
+ TRAP(err, err = QtMainWrapper());
delete cleanupStack;
return err;
diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp
index edc2fb8..b9a720b 100644
--- a/src/s60main/qts60main_mcrt0.cpp
+++ b/src/s60main/qts60main_mcrt0.cpp
@@ -6,35 +6,33 @@
**
** This file is part of the Symbian application wrapper 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_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index dc0e0d0..1879367 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -33,6 +33,7 @@
#include "qscriptvalue_p.h"
#include "qscriptvalueiterator.h"
#include "qscriptclass.h"
+#include "qscriptcontextinfo.h"
#include "qscriptprogram.h"
#include "qscriptprogram_p.h"
#include "qdebug.h"
@@ -698,9 +699,9 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS
return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number");
#ifndef QT_NO_QOBJECT
QString context;
-// ### implement context resolution
-// if (ctx->parentContext())
-// context = QFileInfo(ctx->parentContext()->fileName()).baseName();
+ QScriptContext *ctx = QScriptEnginePrivate::contextForFrame(exec);
+ if (ctx && ctx->parentContext())
+ context = QFileInfo(QScriptContextInfo(ctx->parentContext()).fileName()).baseName();
#endif
QString text(args.at(0).toString(exec));
#ifndef QT_NO_QOBJECT
@@ -1101,16 +1102,6 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
}
}
-#ifndef QT_NO_QOBJECT
- {
- QHash<QObject*, QScript::QObjectData*>::const_iterator it;
- for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
- QScript::QObjectData *qdata = it.value();
- qdata->mark(markStack);
- }
- }
-#endif
-
{
QHash<int, QScriptTypeInfo*>::const_iterator it;
for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) {
@@ -1134,6 +1125,17 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
context = context->parentContext();
}
}
+
+#ifndef QT_NO_QOBJECT
+ markStack.drain(); // make sure everything is marked before marking qobject data
+ {
+ QHash<QObject*, QScript::QObjectData*>::const_iterator it;
+ for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
+ QScript::QObjectData *qdata = it.value();
+ qdata->mark(markStack);
+ }
+ }
+#endif
}
bool QScriptEnginePrivate::isCollecting() const
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp
index 559fcd3..63ba9ec 100644
--- a/src/script/bridge/qscriptqobject.cpp
+++ b/src/script/bridge/qscriptqobject.cpp
@@ -83,22 +83,23 @@ struct QObjectConnection
void mark(JSC::MarkStack& markStack)
{
- // ### need to find out if senderWrapper is marked
if (senderWrapper) {
- // see if the sender should be marked or not
+ // see if the sender should be marked or not;
+ // if the C++ object is owned by script, we don't want
+ // it to stay alive due to a script connection.
Q_ASSERT(senderWrapper.inherits(&QScriptObject::info));
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper));
- QScriptObjectDelegate *delegate = scriptObject->delegate();
- Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
- QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate);
- if ((inst->ownership() == QScriptEngine::ScriptOwnership)
- || ((inst->ownership() == QScriptEngine::AutoOwnership)
- && inst->value() && !inst->value()->parent())) {
- // #### don't mark if not marked otherwise
- //senderWrapper = JSC::JSValue();
- markStack.append(senderWrapper);
- } else {
- markStack.append(senderWrapper);
+ if (!JSC::Heap::isCellMarked(scriptObject)) {
+ QScriptObjectDelegate *delegate = scriptObject->delegate();
+ Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
+ QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate);
+ if ((inst->ownership() == QScriptEngine::ScriptOwnership)
+ || ((inst->ownership() == QScriptEngine::AutoOwnership)
+ && inst->value() && !inst->value()->parent())) {
+ senderWrapper = JSC::JSValue();
+ } else {
+ markStack.append(senderWrapper);
+ }
}
}
if (receiver)
diff --git a/src/script/script.pro b/src/script/script.pro
index 008c556..771047a 100644
--- a/src/script/script.pro
+++ b/src/script/script.pro
@@ -1,7 +1,7 @@
TARGET = QtScript
QPRO_PWD = $$PWD
QT = core
-DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror
+DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror WTF=QTWTF
DEFINES += QT_BUILD_SCRIPT_LIB
DEFINES += QT_NO_USING_NAMESPACE
DEFINES += QLALR_NO_QSCRIPTGRAMMAR_DEBUG_INFO
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 3f13405..5d039cf 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -1025,7 +1025,6 @@ QVariant QDB2Result::data(int field)
break;
case QVariant::Double:
{
- QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull);
switch(numericalPrecisionPolicy()) {
case QSql::LowPrecisionInt32:
v = new QVariant(qGetIntData(d->hStmt, field, isNull));
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index 17f2c92..a384ba0 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -517,7 +517,7 @@ QVariant::Type qDecodeOCIType(const QString& ocitype, QSql::NumericalPrecisionPo
}
else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB")
|| ocitype == QLatin1String("CLOB"))
- type = QVariant::ByteArray;
+ type = QVariant::String;
else if (ocitype == QLatin1String("RAW") || ocitype == QLatin1String("LONG RAW")
|| ocitype == QLatin1String("ROWID") || ocitype == QLatin1String("BLOB")
|| ocitype == QLatin1String("CFILE") || ocitype == QLatin1String("BFILE"))
@@ -543,6 +543,7 @@ QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precis
case SQLT_AVC:
case SQLT_RDD:
case SQLT_LNG:
+ case SQLT_CLOB:
#ifdef SQLT_INTERVAL_YM
case SQLT_INTERVAL_YM:
#endif
@@ -584,7 +585,6 @@ QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precis
case SQLT_NTY:
case SQLT_REF:
case SQLT_RID:
- case SQLT_CLOB:
type = QVariant::ByteArray;
break;
case SQLT_DAT:
@@ -2200,26 +2200,34 @@ bool QOCIDriver::rollbackTransaction()
QStringList QOCIDriver::tables(QSql::TableType type) const
{
QStringList tl;
+ QStringList sysUsers = QStringList() << QLatin1String("MDSYS")
+ << QLatin1String("LBACSYS")
+ << QLatin1String("SYS")
+ << QLatin1String("SYSTEM")
+ << QLatin1String("WKSYS")
+ << QLatin1String("CTXSYS")
+ << QLatin1String("WMSYS");
+
+ QString user = d->user;
+ if ( isIdentifierEscaped(user, QSqlDriver::TableName))
+ user = stripDelimiters(user, QSqlDriver::TableName);
+ else
+ user = user.toUpper();
+
+ if(sysUsers.contains(user))
+ sysUsers.removeAll(user);;
+
if (!isOpen())
return tl;
QSqlQuery t(createResult());
t.setForwardOnly(true);
if (type & QSql::Tables) {
- t.exec(QLatin1String("select owner, table_name from all_tables "
- "where owner != 'MDSYS' "
- "and owner != 'LBACSYS' "
- "and owner != 'SYS' "
- "and owner != 'SYSTEM' "
- "and owner != 'WKSYS'"
- "and owner != 'CTXSYS'"
- "and owner != 'WMSYS'"));
-
- QString user = d->user;
- if ( isIdentifierEscaped(user, QSqlDriver::TableName))
- user = stripDelimiters(user, QSqlDriver::TableName);
- else
- user = user.toUpper();
+ QString query = QLatin1String("select owner, table_name from all_tables where ");
+ QStringList whereList;
+ foreach(const QString &sysUserName, sysUsers)
+ whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' ");
+ t.exec(query + whereList.join(QLatin1String(" and ")));
while (t.next()) {
if (t.value(0).toString().toUpper() != user.toUpper())
@@ -2229,30 +2237,21 @@ QStringList QOCIDriver::tables(QSql::TableType type) const
}
// list all table synonyms as well
- t.exec(QLatin1String("select owner, synonym_name from all_synonyms "
- "where owner != 'MDSYS' "
- "and owner != 'LBACSYS' "
- "and owner != 'SYS' "
- "and owner != 'SYSTEM' "
- "and owner != 'WKSYS'"
- "and owner != 'CTXSYS'"
- "and owner != 'WMSYS'"));
+ query = QLatin1String("select owner, synonym_name from all_synonyms where ");
+ t.exec(query + whereList.join(QLatin1String(" and ")));
while (t.next()) {
if (t.value(0).toString() != d->user)
- tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString());
+ tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
else
tl.append(t.value(1).toString());
}
}
if (type & QSql::Views) {
- t.exec(QLatin1String("select owner, view_name from all_views "
- "where owner != 'MDSYS' "
- "and owner != 'LBACSYS' "
- "and owner != 'SYS' "
- "and owner != 'SYSTEM' "
- "and owner != 'WKSYS'"
- "and owner != 'CTXSYS'"
- "and owner != 'WMSYS'"));
+ QString query = QLatin1String("select owner, view_name from all_views where ");
+ QStringList whereList;
+ foreach(const QString &sysUserName, sysUsers)
+ whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' ");
+ t.exec(query + whereList.join(QLatin1String(" and ")));
while (t.next()) {
if (t.value(0).toString().toUpper() != d->user.toUpper())
tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
@@ -2265,6 +2264,28 @@ QStringList QOCIDriver::tables(QSql::TableType type) const
while (t.next()) {
tl.append(t.value(0).toString());
}
+ QString query = QLatin1String("select owner, table_name from all_tables where ");
+ QStringList whereList;
+ foreach(const QString &sysUserName, sysUsers)
+ whereList << QLatin1String("owner = '") + sysUserName + QLatin1String("' ");
+ t.exec(query + whereList.join(QLatin1String(" or ")));
+
+ while (t.next()) {
+ if (t.value(0).toString().toUpper() != user.toUpper())
+ tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
+ else
+ tl.append(t.value(1).toString());
+ }
+
+ // list all table synonyms as well
+ query = QLatin1String("select owner, synonym_name from all_synonyms where ");
+ t.exec(query + whereList.join(QLatin1String(" or ")));
+ while (t.next()) {
+ if (t.value(0).toString() != d->user)
+ tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString());
+ else
+ tl.append(t.value(1).toString());
+ }
}
return tl;
}
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index e686873..fdf0c2c 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -172,28 +172,39 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode
SQLSMALLINT msgLen = 0;
SQLRETURN r = SQL_NO_DATA;
SQLTCHAR state_[SQL_SQLSTATE_SIZE+1];
- SQLTCHAR description_[SQL_MAX_MESSAGE_LENGTH];
+ QVarLengthArray<SQLTCHAR> description_(SQL_MAX_MESSAGE_LENGTH);
QString result;
int i = 1;
description_[0] = 0;
+ r = SQLGetDiagRec(handleType,
+ handle,
+ i,
+ state_,
+ &nativeCode_,
+ 0,
+ NULL,
+ &msgLen);
+ if(r == SQL_NO_DATA)
+ return QString();
+ description_.resize(msgLen+1);
do {
r = SQLGetDiagRec(handleType,
handle,
i,
- (SQLTCHAR*)state_,
+ state_,
&nativeCode_,
- (SQLTCHAR*)description_,
- SQL_MAX_MESSAGE_LENGTH, /* in bytes, not in characters */
+ description_.data(),
+ description_.size(),
&msgLen);
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
if (nativeCode)
*nativeCode = nativeCode_;
QString tmpstore;
#ifdef UNICODE
- tmpstore = QString((const QChar*)description_, msgLen);
+ tmpstore = QString((const QChar*)description_.data(), msgLen);
#else
- tmpstore = QString::fromLocal8Bit((const char*)description_, msgLen);
+ tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen);
#endif
if(result != tmpstore) {
if(!result.isEmpty())
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 8355de2..c62f15c 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -122,14 +122,14 @@ public:
sqlite3_stmt *stmt;
- uint skippedStatus: 1; // the status of the fetchNext() that's skipped
- uint skipRow: 1; // skip the next fetchNext()?
- uint utf8: 1;
+ bool skippedStatus; // the status of the fetchNext() that's skipped
+ bool skipRow; // skip the next fetchNext()?
QSqlRecord rInf;
+ QVector<QVariant> firstRow;
};
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
- stmt(0), skippedStatus(false), skipRow(false), utf8(false)
+ stmt(0), skippedStatus(false), skipRow(false)
{
}
@@ -189,10 +189,17 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
// already fetched
Q_ASSERT(!initialFetch);
skipRow = false;
+ for(int i=0;i<firstRow.count();i++)
+ values[i]=firstRow[i];
return skippedStatus;
}
skipRow = initialFetch;
+ if(initialFetch) {
+ firstRow.clear();
+ firstRow.resize(sqlite3_column_count(stmt));
+ }
+
if (!stmt) {
q->setLastError(QSqlError(QCoreApplication::translate("QSQLiteResult", "Unable to fetch row"),
QCoreApplication::translate("QSQLiteResult", "No query"), QSqlError::ConnectionError));
@@ -399,7 +406,7 @@ bool QSQLiteResult::exec()
"Parameter count mismatch"), QString(), QSqlError::StatementError));
return false;
}
- d->skippedStatus = d->fetchNext(cache(), 0, true);
+ d->skippedStatus = d->fetchNext(d->firstRow, 0, true);
if (lastError().isValid()) {
setSelect(false);
setActive(false);
diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp
index b4a9241..2e4d19e 100644
--- a/src/sql/kernel/qsqlcachedresult.cpp
+++ b/src/sql/kernel/qsqlcachedresult.cpp
@@ -278,6 +278,11 @@ bool QSqlCachedResult::cacheNext()
if (d->atEnd)
return false;
+ if(isForwardOnly()) {
+ d->cache.clear();
+ d->cache.resize(d->colCount);
+ }
+
if (!gotoNext(d->cache, d->nextIndex())) {
d->revertLast();
d->atEnd = true;
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 5f0a35d..aec54d6 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -563,7 +563,7 @@ QString QSqlRelationalTableModel::selectStatement() const
// If there are duplicate field names they must be aliased
if (fieldNames.value(fieldList[i]) > 1) {
- QString relTableName = relation.tableName();
+ QString relTableName = relation.tableName().section(QChar::fromLatin1('.'), -1, -1);
if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName))
relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName);
QString displayColumn = relation.displayColumn();
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 3ed918e..21c947b 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -1147,12 +1147,12 @@ static QMatrix parseTransformationMatrix(const QStringRef &value)
if (points.count() != 1)
goto error;
const qreal deg2rad = qreal(0.017453292519943295769);
- matrix.shear(tan(points[0]*deg2rad), 0);
+ matrix.shear(qTan(points[0]*deg2rad), 0);
} else if (state == SkewY) {
if (points.count() != 1)
goto error;
const qreal deg2rad = qreal(0.017453292519943295769);
- matrix.shear(0, tan(points[0]*deg2rad));
+ matrix.shear(0, qTan(points[0]*deg2rad));
}
}
error:
@@ -1481,8 +1481,8 @@ static void pathArc(QPainterPath &path,
yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
/* (xc, yc) is center of the circle. */
- th0 = atan2(y0 - yc, x0 - xc);
- th1 = atan2(y1 - yc, x1 - xc);
+ th0 = qAtan2(y0 - yc, x0 - xc);
+ th1 = qAtan2(y1 - yc, x1 - xc);
th_arc = th1 - th0;
if (th_arc < 0 && sweep_flag)
@@ -1578,8 +1578,8 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
count--;
break;
}
- x = x0 = num[0] + offsetX;
- y = y0 = num[1] + offsetY;
+ x = num[0] + offsetX;
+ y = num[1] + offsetY;
num += 2;
count -= 2;
path.lineTo(x, y);
@@ -1592,8 +1592,8 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
count--;
break;
}
- x = x0 = num[0];
- y = y0 = num[1];
+ x = num[0];
+ y = num[1];
num += 2;
count -= 2;
path.lineTo(x, y);
@@ -2864,14 +2864,8 @@ static QSvgNode *createPolygonNode(QSvgNode *parent,
const QChar *s = pointsStr.constData();
QVector<qreal> points = parseNumbersList(s);
QPolygonF poly(points.count()/2);
- int i = 0;
- QVector<qreal>::const_iterator itr = points.constBegin();
- while (itr != points.constEnd()) {
- qreal one = *itr; ++itr;
- qreal two = *itr; ++itr;
- poly[i] = QPointF(one, two);
- ++i;
- }
+ for (int i = 0; i < poly.size(); ++i)
+ poly[i] = QPointF(points.at(2 * i), points.at(2 * i + 1));
QSvgNode *polygon = new QSvgPolygon(parent, poly);
return polygon;
}
@@ -2886,14 +2880,8 @@ static QSvgNode *createPolylineNode(QSvgNode *parent,
const QChar *s = pointsStr.constData();
QVector<qreal> points = parseNumbersList(s);
QPolygonF poly(points.count()/2);
- int i = 0;
- QVector<qreal>::const_iterator itr = points.constBegin();
- while (itr != points.constEnd()) {
- qreal one = *itr; ++itr;
- qreal two = *itr; ++itr;
- poly[i] = QPointF(one, two);
- ++i;
- }
+ for (int i = 0; i < poly.size(); ++i)
+ poly[i] = QPointF(points.at(2 * i), points.at(2 * i + 1));
QSvgNode *line = new QSvgPolyline(parent, poly);
return line;
diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp
index 57927fd..c67f7d2 100644
--- a/src/svg/qsvgstyle.cpp
+++ b/src/svg/qsvgstyle.cpp
@@ -771,7 +771,7 @@ void QSvgAnimateTransform::resolveMatrix(QSvgNode *node)
qreal transXDiff = (to1-from1) * percentOfAnimation;
qreal transX = from1 + transXDiff;
m_transform = QTransform();
- m_transform.shear(tan(transX * deg2rad), 0);
+ m_transform.shear(qTan(transX * deg2rad), 0);
break;
}
case SkewY: {
@@ -786,7 +786,7 @@ void QSvgAnimateTransform::resolveMatrix(QSvgNode *node)
qreal transYDiff = (to1 - from1) * percentOfAnimation;
qreal transY = from1 + transYDiff;
m_transform = QTransform();
- m_transform.shear(0, tan(transY * deg2rad));
+ m_transform.shear(0, qTan(transY * deg2rad));
break;
}
default:
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 8fcc0df..1a75cf6 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -725,16 +725,6 @@ void Generator::generateMetacall()
needEditable |= p.editable.endsWith(')');
needUser |= p.user.endsWith(')');
}
- bool needAnything = needGet
- | needSet
- | needReset
- | needDesignable
- | needScriptable
- | needStored
- | needEditable
- | needUser;
- if (!needAnything)
- goto skip_properties;
fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n ");
if (needElse)
@@ -904,7 +894,6 @@ void Generator::generateMetacall()
fprintf(out, "\n#endif // QT_NO_PROPERTIES");
}
- skip_properties:
if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size())
fprintf(out, "\n ");
fprintf(out,"return _id;\n}\n");
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 0a87412..27ec3bd 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -3063,11 +3063,11 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
Aspects of the parsing behavior can be adapted using setFeature()
and setProperty().
+ \snippet doc/src/snippets/code/src_xml_sax_qxml.cpp 0
+
QXmlSimpleReader is not reentrant. If you want to use the class
in threaded code, lock the code using QXmlSimpleReader with a
locking mechanism, such as a QMutex.
-
- \snippet doc/src/snippets/code/src_xml_sax_qxml.cpp 0
*/
static inline bool is_S(QChar ch)
diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri
index 9fcc2f5..a0adf75 100644
--- a/src/xmlpatterns/api/api.pri
+++ b/src/xmlpatterns/api/api.pri
@@ -1,59 +1,57 @@
-HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
- $$PWD/qabstractmessagehandler.h \
- $$PWD/qabstracturiresolver.h \
- $$PWD/qabstractxmlnodemodel.h \
- $$PWD/qabstractxmlnodemodel_p.h \
- $$PWD/qabstractxmlpullprovider_p.h \
- $$PWD/qabstractxmlreceiver.h \
- $$PWD/qabstractxmlreceiver_p.h \
- $$PWD/qdeviceresourceloader_p.h \
- $$PWD/qiodevicedelegate_p.h \
- $$PWD/qnetworkaccessdelegator_p.h \
- $$PWD/qpullbridge_p.h \
- $$PWD/qresourcedelegator_p.h \
- $$PWD/qsimplexmlnodemodel.h \
- $$PWD/qsourcelocation.h \
- $$PWD/quriloader_p.h \
- $$PWD/qvariableloader_p.h \
- $$PWD/qxmlformatter.h \
- $$PWD/qxmlname.h \
- $$PWD/qxmlnamepool.h \
- $$PWD/qxmlquery.h \
- $$PWD/qxmlquery_p.h \
- $$PWD/qxmlresultitems.h \
- $$PWD/qxmlresultitems_p.h \
- $$PWD/qxmlschema.h \
- $$PWD/qxmlschema_p.h \
- $$PWD/qxmlschemavalidator.h \
- $$PWD/qxmlschemavalidator_p.h \
- $$PWD/qxmlserializer.h \
- $$PWD/qxmlserializer_p.h \
- $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler_p.h \
- $$PWD/../../../tools/xmlpatterns/qcoloroutput_p.h
-
-SOURCES += $$PWD/qvariableloader.cpp \
- $$PWD/qabstractmessagehandler.cpp \
- $$PWD/qabstracturiresolver.cpp \
- $$PWD/qabstractxmlnodemodel.cpp \
- $$PWD/qabstractxmlpullprovider.cpp \
- $$PWD/qabstractxmlreceiver.cpp \
- $$PWD/qiodevicedelegate.cpp \
- $$PWD/qnetworkaccessdelegator.cpp \
- $$PWD/qpullbridge.cpp \
- $$PWD/qresourcedelegator.cpp \
- $$PWD/qsimplexmlnodemodel.cpp \
- $$PWD/qsourcelocation.cpp \
- $$PWD/quriloader.cpp \
- $$PWD/qxmlformatter.cpp \
- $$PWD/qxmlname.cpp \
- $$PWD/qxmlnamepool.cpp \
- $$PWD/qxmlquery.cpp \
- $$PWD/qxmlresultitems.cpp \
- $$PWD/qxmlschema.cpp \
- $$PWD/qxmlschema_p.cpp \
- $$PWD/qxmlschemavalidator.cpp \
- $$PWD/qxmlserializer.cpp \
- $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler.cpp \
- $$PWD/../../../tools/xmlpatterns/qcoloroutput.cpp
-
-INCLUDEPATH += $$PWD/../../../tools/xmlpatterns/
+HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \
+ $$PWD/qabstractmessagehandler.h \
+ $$PWD/qabstracturiresolver.h \
+ $$PWD/qabstractxmlnodemodel.h \
+ $$PWD/qabstractxmlnodemodel_p.h \
+ $$PWD/qabstractxmlpullprovider_p.h \
+ $$PWD/qabstractxmlreceiver.h \
+ $$PWD/qabstractxmlreceiver_p.h \
+ $$PWD/qdeviceresourceloader_p.h \
+ $$PWD/qiodevicedelegate_p.h \
+ $$PWD/qnetworkaccessdelegator_p.h \
+ $$PWD/qpullbridge_p.h \
+ $$PWD/qresourcedelegator_p.h \
+ $$PWD/qsimplexmlnodemodel.h \
+ $$PWD/qsourcelocation.h \
+ $$PWD/quriloader_p.h \
+ $$PWD/qvariableloader_p.h \
+ $$PWD/qxmlformatter.h \
+ $$PWD/qxmlname.h \
+ $$PWD/qxmlnamepool.h \
+ $$PWD/qxmlquery.h \
+ $$PWD/qxmlquery_p.h \
+ $$PWD/qxmlresultitems.h \
+ $$PWD/qxmlresultitems_p.h \
+ $$PWD/qxmlschema.h \
+ $$PWD/qxmlschema_p.h \
+ $$PWD/qxmlschemavalidator.h \
+ $$PWD/qxmlschemavalidator_p.h \
+ $$PWD/qxmlserializer.h \
+ $$PWD/qxmlserializer_p.h \
+ $$PWD/qcoloringmessagehandler_p.h \
+ $$PWD/qcoloroutput_p.h \
+ $$PWD/qxmlpatternistcli_p.h
+SOURCES += $$PWD/qvariableloader.cpp \
+ $$PWD/qabstractmessagehandler.cpp \
+ $$PWD/qabstracturiresolver.cpp \
+ $$PWD/qabstractxmlnodemodel.cpp \
+ $$PWD/qabstractxmlpullprovider.cpp \
+ $$PWD/qabstractxmlreceiver.cpp \
+ $$PWD/qiodevicedelegate.cpp \
+ $$PWD/qnetworkaccessdelegator.cpp \
+ $$PWD/qpullbridge.cpp \
+ $$PWD/qresourcedelegator.cpp \
+ $$PWD/qsimplexmlnodemodel.cpp \
+ $$PWD/qsourcelocation.cpp \
+ $$PWD/quriloader.cpp \
+ $$PWD/qxmlformatter.cpp \
+ $$PWD/qxmlname.cpp \
+ $$PWD/qxmlnamepool.cpp \
+ $$PWD/qxmlquery.cpp \
+ $$PWD/qxmlresultitems.cpp \
+ $$PWD/qxmlschema.cpp \
+ $$PWD/qxmlschema_p.cpp \
+ $$PWD/qxmlschemavalidator.cpp \
+ $$PWD/qxmlserializer.cpp \
+ $$PWD/qcoloringmessagehandler.cpp \
+ $$PWD/qcoloroutput.cpp
diff --git a/src/xmlpatterns/api/qcoloringmessagehandler.cpp b/src/xmlpatterns/api/qcoloringmessagehandler.cpp
new file mode 100644
index 0000000..7d3eb6f
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloringmessagehandler.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore 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 <QXmlStreamReader>
+
+#include "qcoloringmessagehandler_p.h"
+#include "qxmlpatternistcli_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ColoringMessageHandler::ColoringMessageHandler(QObject *parent) : QAbstractMessageHandler(parent)
+{
+ m_classToColor.insert(QLatin1String("XQuery-data"), Data);
+ m_classToColor.insert(QLatin1String("XQuery-expression"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-function"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-keyword"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-type"), Keyword);
+ m_classToColor.insert(QLatin1String("XQuery-uri"), Data);
+ m_classToColor.insert(QLatin1String("XQuery-filepath"), Data);
+
+ /* If you're tuning the colors, take it easy laddie. Take into account:
+ *
+ * - Get over your own taste, there's others too on this planet
+ * - Make sure it works well on black & white
+ * - Make sure it works well on white & black
+ */
+ insertMapping(Location, CyanForeground);
+ insertMapping(ErrorCode, RedForeground);
+ insertMapping(Keyword, BlueForeground);
+ insertMapping(Data, BlueForeground);
+ insertMapping(RunningText, DefaultColor);
+}
+
+void ColoringMessageHandler::handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation)
+{
+ const bool hasLine = sourceLocation.line() != -1;
+
+ switch(type)
+ {
+ case QtWarningMsg:
+ {
+ if(hasLine)
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Warning in %1, at line %2, column %3: %4").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()),
+ QString::number(sourceLocation.line()),
+ QString::number(sourceLocation.column()),
+ colorifyDescription(description)));
+ }
+ else
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Warning in %1: %2").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()),
+ colorifyDescription(description)));
+ }
+
+ break;
+ }
+ case QtFatalMsg:
+ {
+ const QString errorCode(identifier.fragment());
+ Q_ASSERT(!errorCode.isEmpty());
+ QUrl uri(identifier);
+ uri.setFragment(QString());
+
+ QString location;
+
+ if(sourceLocation.isNull())
+ location = QXmlPatternistCLI::tr("Unknown location");
+ else
+ location = QString::fromLatin1(sourceLocation.uri().toEncoded());
+
+ QString errorId;
+ /* If it's a standard error code, we don't want to output the
+ * whole URI. */
+ if(uri.toString() == QLatin1String("http://www.w3.org/2005/xqt-errors"))
+ errorId = errorCode;
+ else
+ errorId = QString::fromLatin1(identifier.toEncoded());
+
+ if(hasLine)
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode),
+ colorify(location, Location),
+ colorify(QString::number(sourceLocation.line()), Location),
+ colorify(QString::number(sourceLocation.column()), Location),
+ colorifyDescription(description)));
+ }
+ else
+ {
+ writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode),
+ colorify(location, Location),
+ colorifyDescription(description)));
+ }
+ break;
+ }
+ case QtCriticalMsg:
+ /* Fallthrough. */
+ case QtDebugMsg:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "message() is not supposed to receive QtCriticalMsg or QtDebugMsg.");
+ return;
+ }
+ }
+}
+
+QString ColoringMessageHandler::colorifyDescription(const QString &in) const
+{
+ QXmlStreamReader reader(in);
+ QString result;
+ result.reserve(in.size());
+ ColorType currentColor = RunningText;
+
+ while(!reader.atEnd())
+ {
+ reader.readNext();
+
+ switch(reader.tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(reader.name() == QLatin1String("span"))
+ {
+ Q_ASSERT(m_classToColor.contains(reader.attributes().value(QLatin1String("class")).toString()));
+ currentColor = m_classToColor.value(reader.attributes().value(QLatin1String("class")).toString());
+ }
+
+ continue;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ result.append(colorify(reader.text().toString(), currentColor));
+ continue;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ currentColor = RunningText;
+ continue;
+ }
+ /* Fallthrough, */
+ case QXmlStreamReader::StartDocument:
+ /* Fallthrough, */
+ case QXmlStreamReader::EndDocument:
+ continue;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Unexpected node.");
+ }
+ }
+
+ Q_ASSERT_X(!reader.hasError(), Q_FUNC_INFO,
+ "The output from Patternist must be well-formed.");
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qcoloringmessagehandler_p.h b/src/xmlpatterns/api/qcoloringmessagehandler_p.h
new file mode 100644
index 0000000..3e8d18b
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloringmessagehandler_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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$
+**
+****************************************************************************/
+
+//
+// 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.
+
+#ifndef Patternist_ColoringMessageHandler_h
+#define Patternist_ColoringMessageHandler_h
+
+#include <QHash>
+
+#include "qcoloroutput_p.h"
+#include "qabstractmessagehandler.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ColoringMessageHandler : public QAbstractMessageHandler
+ , private ColorOutput
+ {
+ public:
+ ColoringMessageHandler(QObject *parent = 0);
+
+ protected:
+ virtual void handleMessage(QtMsgType type,
+ const QString &description,
+ const QUrl &identifier,
+ const QSourceLocation &sourceLocation);
+
+ private:
+ QString colorifyDescription(const QString &in) const;
+
+ enum ColorType
+ {
+ RunningText,
+ Location,
+ ErrorCode,
+ Keyword,
+ Data
+ };
+
+ QHash<QString, ColorType> m_classToColor;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qcoloroutput.cpp b/src/xmlpatterns/api/qcoloroutput.cpp
new file mode 100644
index 0000000..4f27fd5
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloroutput.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns 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 <QFile>
+#include <QHash>
+#include <QTextCodec>
+
+#include "qcoloroutput_p.h"
+
+// TODO: rename insertMapping() to insertColorMapping()
+// TODO: Use a smart pointer for managing ColorOutputPrivate *d;
+// TODO: break out the C++ example into a snippet file
+
+/* This include must appear here, because if it appears at the beginning of the file for
+ * instance, it breaks build -- "qglobal.h:628: error: template with
+ * C linkage" -- on Mac OS X 10.4. */
+#ifndef Q_OS_WIN
+#include <unistd.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ class ColorOutputPrivate
+ {
+ public:
+ ColorOutputPrivate() : currentColorID(-1)
+
+ {
+ /* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance
+ * is considered of lower priority.
+ */
+ m_out.open(stderr, QIODevice::WriteOnly | QIODevice::Unbuffered);
+
+ coloringEnabled = isColoringPossible();
+ }
+
+ ColorOutput::ColorMapping colorMapping;
+ int currentColorID;
+ bool coloringEnabled;
+
+ static const char *const foregrounds[];
+ static const char *const backgrounds[];
+
+ inline void write(const QString &msg)
+ {
+ m_out.write(msg.toLocal8Bit());
+ }
+
+ static QString escapeCode(const QString &in)
+ {
+ QString result;
+ result.append(QChar(0x1B));
+ result.append(QLatin1Char('['));
+ result.append(in);
+ result.append(QLatin1Char('m'));
+ return result;
+ }
+
+ private:
+ QFile m_out;
+
+ /*!
+ Returns true if it's suitable to send colored output to \c stderr.
+ */
+ inline bool isColoringPossible() const
+ {
+# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ /* Windows doesn't at all support ANSI escape codes, unless
+ * the user install a "device driver". See the Wikipedia links in the
+ * class documentation for details. */
+ return false;
+# else
+ /* We use QFile::handle() to get the file descriptor. It's a bit unsure
+ * whether it's 2 on all platforms and in all cases, so hopefully this layer
+ * of abstraction helps handle such cases. */
+ return isatty(m_out.handle());
+# endif
+ }
+ };
+}
+
+const char *const ColorOutputPrivate::foregrounds[] =
+{
+ "0;30",
+ "0;34",
+ "0;32",
+ "0;36",
+ "0;31",
+ "0;35",
+ "0;33",
+ "0;37",
+ "1;30",
+ "1;34",
+ "1;32",
+ "1;36",
+ "1;31",
+ "1;35",
+ "1;33",
+ "1;37"
+};
+
+const char *const ColorOutputPrivate::backgrounds[] =
+{
+ "0;40",
+ "0;44",
+ "0;42",
+ "0;46",
+ "0;41",
+ "0;45",
+ "0;43"
+};
+
+/*!
+ \since 4.4
+ \nonreentrant
+ \brief Outputs colored messages to \c stderr.
+ \internal
+
+ ColorOutput is a convenience class for outputting messages to \c stderr
+ using color escape codes, as mandated in ECMA-48. ColorOutput will only
+ color output when it is detected to be suitable. For instance, if \c stderr is
+ detected to be attached to a file instead of a TTY, no coloring will be done.
+
+ ColorOutput does its best attempt. but it is generally undefined what coloring
+ or effect the various coloring flags has. It depends strongly on what terminal
+ software that is being used.
+
+ When using `echo -e 'my escape sequence'`, \033 works as an initiator but not
+ when printing from a C++ program, despite having escaped the backslash.
+ That's why we below use characters with value 0x1B.
+
+ It can be convenient to subclass ColorOutput with a private scope, such that the
+ functions are directly available in the class using it.
+
+ \section1 Usage
+
+ To output messages, call write() or writeUncolored(). write() takes as second
+ argument an integer, which ColorOutput uses as a lookup key to find the color
+ it should color the text in. The mapping from keys to colors is done using
+ insertMapping(). Typically this is used by having enums for the various kinds
+ of messages, which subsequently are registered.
+
+ \code
+ enum MyMessage
+ {
+ Error,
+ Important
+ };
+
+ ColorOutput output;
+ output.insertMapping(Error, ColorOutput::RedForeground);
+ output.insertMapping(Import, ColorOutput::BlueForeground);
+
+ output.write("This is important", Important);
+ output.write("Jack, I'm only the selected official!", Error);
+ \endcode
+
+ \sa {http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html} {Bash Prompt HOWTO, 6.1. Colours}
+ {http://linuxgazette.net/issue51/livingston-blade.html} {Linux Gazette, Tweaking Eterm, Edward Livingston-Blade}
+ {http://www.ecma-international.org/publications/standards/Ecma-048.htm} {Standard ECMA-48, Control Functions for Coded Character Sets, ECMA International},
+ {http://en.wikipedia.org/wiki/ANSI_escape_code} {Wikipedia, ANSI escape code}
+ {http://linuxgazette.net/issue65/padala.html} {Linux Gazette, So You Like Color!, Pradeep Padala}
+ */
+
+/*!
+ \enum ColorOutput::ColorCode
+
+ \value DefaultColor ColorOutput performs no coloring. This typically means black on white
+ or white on black, depending on the settings of the user's terminal.
+ */
+
+/*!
+ Sets the color mapping to be \a cMapping.
+
+ Negative values are disallowed.
+
+ \sa colorMapping(), insertMapping()
+ */
+void ColorOutput::setColorMapping(const ColorMapping &cMapping)
+{
+ d->colorMapping = cMapping;
+}
+
+/*!
+ Returns the color mappings in use.
+
+ \sa setColorMapping(), insertMapping()
+ */
+ColorOutput::ColorMapping ColorOutput::colorMapping() const
+{
+ return d->colorMapping;
+}
+
+/*!
+ Constructs a ColorOutput instance, ready for use.
+ */
+ColorOutput::ColorOutput() : d(new ColorOutputPrivate())
+{
+}
+
+/*!
+ Destructs this ColorOutput instance.
+ */
+ColorOutput::~ColorOutput()
+{
+ delete d;
+}
+
+/*!
+ Sends \a message to \c stderr, using the color looked up in colorMapping() using \a colorID.
+
+ If \a color isn't available in colorMapping(), result and behavior is undefined.
+
+ If \a colorID is 0, which is the default value, the previously used coloring is used. ColorOutput
+ is initialized to not color at all.
+
+ If \a message is empty, effects are undefined.
+
+ \a message will be printed as is. For instance, no line endings will be inserted.
+ */
+void ColorOutput::write(const QString &message, int colorID)
+{
+ d->write(colorify(message, colorID));
+}
+
+/*!
+ Writes \a message to \c stderr as if for instance
+ QTextStream would have been used, and adds a line ending at the end.
+
+ This function can be practical to use such that one can use ColorOutput for all forms of writing.
+ */
+void ColorOutput::writeUncolored(const QString &message)
+{
+ d->write(message + QLatin1Char('\n'));
+}
+
+/*!
+ Treats \a message and \a colorID identically to write(), but instead of writing
+ \a message to \c stderr, it is prepared for being written to \c stderr, but is then
+ returned.
+
+ This is useful when the colored string is inserted into a translated string(dividing
+ the string into several small strings prevents proper translation).
+ */
+QString ColorOutput::colorify(const QString &message, int colorID) const
+{
+ Q_ASSERT_X(colorID == -1 || d->colorMapping.contains(colorID), Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("There is no color registered by id %1").arg(colorID)));
+ Q_ASSERT_X(!message.isEmpty(), Q_FUNC_INFO, "It makes no sense to attempt to print an empty string.");
+
+ if(colorID != -1)
+ d->currentColorID = colorID;
+
+ if(d->coloringEnabled && colorID != -1)
+ {
+ const int color(d->colorMapping.value(colorID));
+
+ /* If DefaultColor is set, we don't want to color it. */
+ if(color & DefaultColor)
+ return message;
+
+ const int foregroundCode = (int(color) & ForegroundMask) >> ForegroundShift;
+ const int backgroundCode = (int(color) & BackgroundMask) >> BackgroundShift;
+ QString finalMessage;
+ bool closureNeeded = false;
+
+ if(foregroundCode)
+ {
+ finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::foregrounds[foregroundCode - 1])));
+ closureNeeded = true;
+ }
+
+ if(backgroundCode)
+ {
+ finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::backgrounds[backgroundCode - 1])));
+ closureNeeded = true;
+ }
+
+ finalMessage.append(message);
+
+ if(closureNeeded)
+ {
+ finalMessage.append(QChar(0x1B));
+ finalMessage.append(QLatin1String("[0m"));
+ }
+
+ return finalMessage;
+ }
+ else
+ return message;
+}
+
+/*!
+ Adds a color mapping from \a colorID to \a colorCode, for this ColorOutput instance.
+
+ This is a convenience function for creating a ColorOutput::ColorMapping instance and
+ calling setColorMapping().
+
+ \sa colorMapping(), setColorMapping()
+ */
+void ColorOutput::insertMapping(int colorID, const ColorCode colorCode)
+{
+ d->colorMapping.insert(colorID, colorCode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/api/qcoloroutput_p.h b/src/xmlpatterns/api/qcoloroutput_p.h
new file mode 100644
index 0000000..1917ec7
--- /dev/null
+++ b/src/xmlpatterns/api/qcoloroutput_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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$
+**
+****************************************************************************/
+
+//
+// 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.
+
+#ifndef Patternist_ColorOutput_h
+#define Patternist_ColorOutput_h
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QHash>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ColorOutputPrivate;
+
+ class ColorOutput
+ {
+ enum
+ {
+ ForegroundShift = 10,
+ BackgroundShift = 20,
+ SpecialShift = 20,
+ ForegroundMask = ((1 << ForegroundShift) - 1) << ForegroundShift,
+ BackgroundMask = ((1 << BackgroundShift) - 1) << BackgroundShift
+ };
+
+ public:
+ enum ColorCodeComponent
+ {
+ BlackForeground = 1 << ForegroundShift,
+ BlueForeground = 2 << ForegroundShift,
+ GreenForeground = 3 << ForegroundShift,
+ CyanForeground = 4 << ForegroundShift,
+ RedForeground = 5 << ForegroundShift,
+ PurpleForeground = 6 << ForegroundShift,
+ BrownForeground = 7 << ForegroundShift,
+ LightGrayForeground = 8 << ForegroundShift,
+ DarkGrayForeground = 9 << ForegroundShift,
+ LightBlueForeground = 10 << ForegroundShift,
+ LightGreenForeground = 11 << ForegroundShift,
+ LightCyanForeground = 12 << ForegroundShift,
+ LightRedForeground = 13 << ForegroundShift,
+ LightPurpleForeground = 14 << ForegroundShift,
+ YellowForeground = 15 << ForegroundShift,
+ WhiteForeground = 16 << ForegroundShift,
+
+ BlackBackground = 1 << BackgroundShift,
+ BlueBackground = 2 << BackgroundShift,
+ GreenBackground = 3 << BackgroundShift,
+ CyanBackground = 4 << BackgroundShift,
+ RedBackground = 5 << BackgroundShift,
+ PurpleBackground = 6 << BackgroundShift,
+ BrownBackground = 7 << BackgroundShift,
+ DefaultColor = 1 << SpecialShift
+ };
+
+ typedef QFlags<ColorCodeComponent> ColorCode;
+ typedef QHash<int, ColorCode> ColorMapping;
+
+ ColorOutput();
+ ~ColorOutput();
+
+ void setColorMapping(const ColorMapping &cMapping);
+ ColorMapping colorMapping() const;
+ void insertMapping(int colorID, const ColorCode colorCode);
+
+ void writeUncolored(const QString &message);
+ void write(const QString &message, int color = -1);
+ QString colorify(const QString &message, int color = -1) const;
+
+ private:
+ ColorOutputPrivate *d;
+ Q_DISABLE_COPY(ColorOutput)
+ };
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPatternist::ColorOutput::ColorCode)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/api/qxmlpatternistcli_p.h b/src/xmlpatterns/api/qxmlpatternistcli_p.h
new file mode 100644
index 0000000..072e4aa
--- /dev/null
+++ b/src/xmlpatterns/api/qxmlpatternistcli_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the XMLPatterns 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$
+**
+****************************************************************************/
+
+//
+// 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.
+
+#ifndef Patternist_Cli_h
+#define Patternist_Cli_h
+
+#include <QCoreApplication>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlPatternistCLI
+{
+public:
+ Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI)
+private:
+ inline QXmlPatternistCLI();
+ Q_DISABLE_COPY(QXmlPatternistCLI)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro
index 1df497d..a224762 100644
--- a/src/xmlpatterns/xmlpatterns.pro
+++ b/src/xmlpatterns/xmlpatterns.pro
@@ -1,15 +1,14 @@
-TARGET = QtXmlPatterns
-QPRO_PWD = $$PWD
-QT = core network
-DEFINES += QT_BUILD_XMLPATTERNS_LIB QT_NO_USING_NAMESPACE
+TARGET = QtXmlPatterns
+QPRO_PWD = $$PWD
+QT = core \
+ network
+DEFINES += QT_BUILD_XMLPATTERNS_LIB \
+ QT_NO_USING_NAMESPACE
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000
-
-unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtNetwork
-
+unix:QMAKE_PKGCONFIG_REQUIRES = QtCore \
+ QtNetwork
include(../qbase.pri)
-
PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
-
include($$PWD/common.pri)
include($$PWD/acceltree/acceltree.pri)
include($$PWD/api/api.pri)
@@ -25,14 +24,13 @@ include($$PWD/schema/schema.pri)
include($$PWD/type/type.pri)
include($$PWD/utils/utils.pri)
include($$PWD/qobjectmodel/qobjectmodel.pri, "", true)
+wince*:# The Microsoft MIPS compiler crashes if /Og is specified
+:
-wince*: {
- # The Microsoft MIPS compiler crashes if /Og is specified
- # -O2/1 expands to /Og plus additional arguments.
- contains(DEFINES, MIPS): {
- QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
- QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
- }
+# -O2/1 expands to /Og plus additional arguments.
+contains(DEFINES, MIPS): {
+ QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
+ QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
}
-
-symbian:TARGET.UID3=0x2001E62B
+symbian:TARGET.UID3 = 0x2001E62B
+HEADERS +=