summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libjpeg/makefile.dj
Commit message (Expand)AuthorAgeFilesLines
* Long live Qt for S60!axis2009-04-241-0/+220
class='add'>.commit-template10
-rw-r--r--FAQ.txt (renamed from FAQ)2
-rw-r--r--LGPL_EXCEPTION.txt (renamed from LGPL_EXCEPTION.TXT)0
-rwxr-xr-xconfig.tests/mac/defaultarch.test33
-rw-r--r--config.tests/unix/opengles1/opengles1.pro2
-rw-r--r--config.tests/unix/opengles1cl/opengles1cl.pro2
-rw-r--r--config.tests/unix/opengles2/opengles2.pro2
-rw-r--r--config.tests/x11/xlib/xlib.cpp9
-rw-r--r--config.tests/x11/xlib/xlib.pro3
-rwxr-xr-xconfigure125
-rw-r--r--configure.exebin1939968 -> 860160 bytes-rw-r--r--demos/embeddeddialogs/customproxy.cpp16
-rw-r--r--demos/embeddeddialogs/customproxy.h1
-rw-r--r--demos/qtdemo/colors.cpp3
-rw-r--r--demos/qtdemo/menumanager.cpp3
-rw-r--r--demos/qtdemo/xml/examples.xml1
-rw-r--r--dist/README2
-rw-r--r--dist/changes-4.5.1574
-rw-r--r--doc/src/custom-types.qdoc114
-rw-r--r--doc/src/debug.qdoc5
-rw-r--r--doc/src/deployment.qdoc67
-rw-r--r--doc/src/designer-manual.qdoc86
-rw-r--r--doc/src/diagrams/qtransform-representation.sk103
-rw-r--r--doc/src/examples.qdoc4
-rw-r--r--doc/src/examples/collidingmice-example.qdoc39
-rw-r--r--doc/src/examples/customtype.qdoc157
-rw-r--r--doc/src/examples/customtypesending.qdoc128
-rw-r--r--doc/src/examples/extension.qdoc11
-rw-r--r--doc/src/examples/queuedcustomtype.qdoc177
-rw-r--r--doc/src/examples/qxmlstreambookmarks.qdoc5
-rw-r--r--doc/src/examples/svggenerator.qdoc136
-rw-r--r--doc/src/exportedfunctions.qdoc6
-rw-r--r--doc/src/external-resources.qdoc5
-rw-r--r--doc/src/graphicsview.qdoc4
-rw-r--r--doc/src/images/customtypesending-example.pngbin0 -> 13305 bytes-rw-r--r--doc/src/images/extension-example.pngbin7676 -> 9929 bytes-rw-r--r--doc/src/images/extension_more.pngbin9309 -> 13523 bytes-rw-r--r--doc/src/images/qtransform-representation.pngbin17892 -> 17385 bytes-rw-r--r--doc/src/images/queuedcustomtype-example.pngbin0 -> 44851 bytes-rw-r--r--doc/src/images/svggenerator-example.pngbin0 -> 11625 bytes-rw-r--r--doc/src/installation.qdoc2
-rw-r--r--doc/src/model-view-programming.qdoc11
-rw-r--r--doc/src/phonon-api.qdoc4
-rw-r--r--doc/src/phonon.qdoc5
-rw-r--r--doc/src/platform-notes.qdoc17
-rw-r--r--doc/src/porting4-removedvirtual.qdocinc2
-rw-r--r--doc/src/qalgorithms.qdoc5
-rw-r--r--doc/src/qaxcontainer.qdoc3
-rw-r--r--doc/src/qaxserver.qdoc3
-rw-r--r--doc/src/qdesktopwidget.qdoc9
-rw-r--r--doc/src/qmake-manual.qdoc10
-rw-r--r--doc/src/qnamespace.qdoc8
-rw-r--r--doc/src/qprintdialog.qdoc32
-rw-r--r--doc/src/qt4-intro.qdoc9
-rw-r--r--doc/src/qtcocoa-known-issues.qdoc168
-rw-r--r--doc/src/sharedlibrary.qdoc186
-rw-r--r--doc/src/snippets/alphachannel.cpp7
-rw-r--r--doc/src/snippets/code/doc_src_deployment.qdoc5
-rw-r--r--doc/src/snippets/code/doc_src_installation.qdoc2
-rw-r--r--doc/src/snippets/code/doc_src_qtestlib.qdoc4
-rw-r--r--doc/src/snippets/code/src_corelib_global_qglobal.cpp8
-rw-r--r--doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp5
-rw-r--r--doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp2
-rw-r--r--doc/src/snippets/code/src_gui_util_qdesktopservices.cpp5
-rw-r--r--doc/src/snippets/qdebug/qdebug.pro1
-rw-r--r--doc/src/snippets/qdebug/qdebugsnippet.cpp (renamed from doc/src/snippets/qdebugsnippet.cpp)12
-rw-r--r--doc/src/snippets/qxmlstreamwriter/main.cpp77
-rw-r--r--doc/src/snippets/qxmlstreamwriter/qxmlstreamwriter.pro2
-rw-r--r--doc/src/snippets/xml/prettyprint/main.cpp2
-rw-r--r--doc/src/trolltech-webpages.qdoc2
-rw-r--r--doc/src/tutorials/addressbook-sdk.qdoc116
-rw-r--r--doc/src/tutorials/widgets-tutorial.qdoc27
-rw-r--r--examples/dialogs/standarddialogs/dialog.cpp6
-rw-r--r--examples/graphicsview/collidingmice/main.cpp4
-rw-r--r--examples/graphicsview/collidingmice/mouse.cpp5
-rw-r--r--examples/graphicsview/collidingmice/mouse.h7
-rw-r--r--examples/itemviews/stardelegate/stardelegate.cpp10
-rw-r--r--examples/itemviews/stardelegate/stardelegate.h6
-rw-r--r--examples/layouts/flowlayout/flowlayout.cpp65
-rw-r--r--examples/layouts/flowlayout/flowlayout.h9
-rw-r--r--examples/painting/painting.pro2
-rw-r--r--examples/painting/svggenerator/displaywidget.cpp149
-rw-r--r--examples/painting/svggenerator/displaywidget.h (renamed from util/scripts/win-binary/nsis/qtnsisext/licensefinder.h)58
-rw-r--r--examples/painting/svggenerator/forms/window.ui249
-rw-r--r--examples/painting/svggenerator/main.cpp (renamed from util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/main.cpp)18
-rw-r--r--examples/painting/svggenerator/resources/shapes.datbin0 -> 2088 bytes-rw-r--r--examples/painting/svggenerator/svggenerator.pro15
-rw-r--r--examples/painting/svggenerator/svggenerator.qrc5
-rw-r--r--examples/painting/svggenerator/window.cpp101
-rw-r--r--examples/painting/svggenerator/window.h (renamed from util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.h)34
-rw-r--r--examples/threads/queuedcustomtype/block.cpp (renamed from util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.cpp)37
-rw-r--r--examples/threads/queuedcustomtype/block.h (renamed from util/scripts/mac-binary/package/InstallerPane/helpfulfunc.h)43
-rw-r--r--examples/threads/queuedcustomtype/main.cpp129
-rw-r--r--examples/threads/queuedcustomtype/queuedcustomtype.pro7
-rw-r--r--examples/threads/queuedcustomtype/renderthread.cpp110
-rw-r--r--examples/threads/queuedcustomtype/renderthread.h77
-rw-r--r--examples/threads/queuedcustomtype/window.cpp137
-rw-r--r--examples/threads/queuedcustomtype/window.h77
-rw-r--r--examples/tools/customtype/customtype.pro3
-rw-r--r--examples/tools/customtype/main.cpp (renamed from util/scripts/mac-binary/package/keydecoder/main.cpp)42
-rw-r--r--examples/tools/customtype/message.cpp90
-rw-r--r--examples/tools/customtype/message.h76
-rw-r--r--examples/tools/customtypesending/customtypesending.pro5
-rw-r--r--examples/tools/customtypesending/main.cpp68
-rw-r--r--examples/tools/customtypesending/message.cpp (renamed from util/scripts/mac-binary/package/InstallerPane/InstallerSecionSection.h)40
-rw-r--r--examples/tools/customtypesending/message.h72
-rw-r--r--examples/tools/customtypesending/window.cpp (renamed from util/scripts/win-binary/nsis/qtnsisext/binpatch.h)65
-rw-r--r--examples/tools/customtypesending/window.h73
-rw-r--r--examples/tutorials/addressbook/README2
-rw-r--r--examples/widgets/movie/movie.pro2
-rw-r--r--examples/xml/xmlstreamlint/main.cpp2
-rw-r--r--examples/xmlpatterns/trafficinfo/mainwindow.cpp2
-rw-r--r--mkspecs/features/include_source_dir.prf1
-rw-r--r--mkspecs/features/moc.prf75
-rw-r--r--mkspecs/features/uic.prf12
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp2
-rw-r--r--qmake/generators/makefile.cpp16
-rw-r--r--qmake/generators/makefile.h6
-rw-r--r--qmake/generators/metamakefile.cpp2
-rw-r--r--qmake/generators/unix/unixmake2.cpp3
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp6
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp2
-rw-r--r--qmake/project.cpp2
-rw-r--r--src/3rdparty/phonon/gstreamer/audiooutput.cpp1
-rw-r--r--src/3rdparty/phonon/gstreamer/mediaobject.cpp100
-rw-r--r--src/3rdparty/phonon/gstreamer/mediaobject.h49
-rw-r--r--src/3rdparty/phonon/gstreamer/x11renderer.cpp1
-rw-r--r--src/3rdparty/phonon/qt7/audionode.mm16
-rw-r--r--src/3rdparty/phonon/qt7/backendinfo.mm1
-rw-r--r--src/3rdparty/phonon/qt7/quicktimevideoplayer.h1
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog156
-rw-r--r--src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMWindow.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMWindow.h2
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp16
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp55
-rw-r--r--src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp16
-rw-r--r--src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp26
-rw-r--r--src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h3
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/PluginView.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/PluginView.h9
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp1
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h2
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp4
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp97
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.h2
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp4
-rw-r--r--src/3rdparty/webkit/WebKit/qt/ChangeLog119
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp39
-rw-r--r--src/activeqt/control/qaxserverbase.cpp15
-rw-r--r--src/corelib/concurrent/qtconcurrentreducekernel.h10
-rw-r--r--src/corelib/global/qfeatures.txt122
-rw-r--r--src/corelib/global/qglobal.cpp72
-rw-r--r--src/corelib/global/qglobal.h9
-rw-r--r--src/corelib/global/qnamespace.h6
-rw-r--r--src/corelib/io/qdebug.cpp257
-rw-r--r--src/corelib/io/qdiriterator.cpp38
-rw-r--r--src/corelib/io/qfile.cpp22
-rw-r--r--src/corelib/io/qfileinfo.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp2
-rw-r--r--src/corelib/io/qprocess.cpp34
-rw-r--r--src/corelib/io/qprocess_unix.cpp8
-rw-r--r--src/corelib/io/qsettings.cpp4
-rw-r--r--src/corelib/io/qsettings_win.cpp51
-rw-r--r--src/corelib/io/qtemporaryfile.cpp2
-rw-r--r--src/corelib/io/qtextstream.cpp2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp8
-rw-r--r--src/corelib/kernel/qcoreevent.h1
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp1
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp15
-rw-r--r--src/corelib/kernel/qmetaobject.cpp18
-rw-r--r--src/corelib/kernel/qmetatype.cpp10
-rw-r--r--src/corelib/kernel/qobject.cpp8
-rw-r--r--src/corelib/kernel/qtranslator.cpp5
-rw-r--r--src/corelib/thread/qatomic.cpp3
-rw-r--r--src/corelib/thread/qmutexpool.cpp15
-rw-r--r--src/corelib/thread/qmutexpool_p.h5
-rw-r--r--src/corelib/thread/qthread.cpp12
-rw-r--r--src/corelib/tools/qlinkedlist.cpp4
-rw-r--r--src/corelib/tools/qlistdata.cpp4
-rw-r--r--src/corelib/tools/qlocale.cpp9
-rw-r--r--src/corelib/tools/qsharedpointer.cpp18
-rw-r--r--src/corelib/tools/qstring.cpp37
-rw-r--r--src/corelib/tools/qvector.h2
-rw-r--r--src/corelib/xml/qxmlstream.cpp13
-rw-r--r--src/dbus/qdbusintegrator.cpp10
-rw-r--r--src/dbus/qdbuspendingreply.h4
-rw-r--r--src/dbus/qdbusthreaddebug_p.h7
-rw-r--r--src/gui/accessible/qaccessible_mac.mm122
-rw-r--r--src/gui/accessible/qaccessiblewidget.cpp13
-rw-r--r--src/gui/dialogs/qcolordialog.cpp8
-rw-r--r--src/gui/dialogs/qfiledialog.cpp71
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm2
-rw-r--r--src/gui/dialogs/qfiledialog_p.h39
-rw-r--r--src/gui/dialogs/qfileinfogatherer.cpp20
-rw-r--r--src/gui/dialogs/qfileinfogatherer_p.h1
-rw-r--r--src/gui/dialogs/qfilesystemmodel.cpp33
-rw-r--r--src/gui/dialogs/qfilesystemmodel_p.h6
-rw-r--r--src/gui/dialogs/qinputdialog.cpp181
-rw-r--r--src/gui/dialogs/qmessagebox.cpp32
-rw-r--r--src/gui/dialogs/qwizard.cpp8
-rw-r--r--src/gui/embedded/qscreen_qws.cpp3
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp552
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h61
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem.cpp45
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp8
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp396
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h4
-rw-r--r--src/gui/graphicsview/qgraphicssceneevent.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp276
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h7
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp60
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h4
-rw-r--r--src/gui/image/qimage.cpp26
-rw-r--r--src/gui/image/qnativeimage.cpp4
-rw-r--r--src/gui/image/qpaintengine_pic.cpp21
-rw-r--r--src/gui/image/qpaintengine_pic_p.h2
-rw-r--r--src/gui/image/qpicture.cpp16
-rw-r--r--src/gui/image/qpicture_p.h1
-rw-r--r--src/gui/image/qpixmap.cpp18
-rw-r--r--src/gui/image/qpixmap_mac.cpp2
-rw-r--r--src/gui/image/qpixmap_x11.cpp6
-rw-r--r--src/gui/image/qpixmapdata_p.h1
-rw-r--r--src/gui/inputmethod/qwininputcontext_win.cpp10
-rw-r--r--src/gui/inputmethod/qximinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qximinputcontext_x11.cpp32
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp13
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp12
-rw-r--r--src/gui/itemviews/qlistview.cpp2
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp25
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.cpp21
-rw-r--r--src/gui/itemviews/qtableview.cpp26
-rw-r--r--src/gui/itemviews/qtableview_p.h3
-rw-r--r--src/gui/itemviews/qtreeview.cpp37
-rw-r--r--src/gui/itemviews/qtreewidget.cpp27
-rw-r--r--src/gui/kernel/qapplication.cpp1913
-rw-r--r--src/gui/kernel/qapplication_x11.cpp40
-rw-r--r--src/gui/kernel/qcocoaapplication_mac.mm22
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm46
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac_p.h1
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm22
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm107
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm67
-rw-r--r--src/gui/kernel/qcocoawindow_mac.mm49
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac.mm41
-rw-r--r--src/gui/kernel/qcursor.h2
-rw-r--r--src/gui/kernel/qcursor_mac.mm16
-rw-r--r--src/gui/kernel/qevent.cpp2
-rw-r--r--src/gui/kernel/qmacdefines_mac.h2
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm5
-rw-r--r--src/gui/kernel/qt_mac.cpp47
-rw-r--r--src/gui/kernel/qt_mac_p.h3
-rw-r--r--src/gui/kernel/qwidget.cpp119
-rw-r--r--src/gui/kernel/qwidget_mac.mm68
-rw-r--r--src/gui/kernel/qwidget_p.h2
-rw-r--r--src/gui/kernel/qwidget_win.cpp2
-rw-r--r--src/gui/kernel/qwidget_x11.cpp7
-rw-r--r--src/gui/kernel/qx11embed_x11.cpp7
-rw-r--r--src/gui/painting/qblendfunctions.cpp28
-rw-r--r--src/gui/painting/qcolor.cpp1
-rw-r--r--src/gui/painting/qmatrix.cpp3
-rw-r--r--src/gui/painting/qpaintengine_alpha.cpp12
-rw-r--r--src/gui/painting/qpaintengine_alpha_p.h1
-rw-r--r--src/gui/painting/qpaintengine_d3d.cpp3
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp114
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp19
-rw-r--r--src/gui/painting/qpaintengineex.cpp3
-rw-r--r--src/gui/painting/qpainter.cpp34
-rw-r--r--src/gui/painting/qpainterpath.cpp23
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpainterpath_p.h11
-rw-r--r--src/gui/painting/qpdf.cpp8
-rw-r--r--src/gui/painting/qprintengine_mac.mm66
-rw-r--r--src/gui/painting/qprintengine_mac_p.h1
-rw-r--r--src/gui/painting/qprintengine_win.cpp7
-rw-r--r--src/gui/painting/qprinter.cpp6
-rw-r--r--src/gui/painting/qregion.cpp24
-rw-r--r--src/gui/painting/qtransform.cpp92
-rw-r--r--src/gui/painting/qtransform.h8
-rw-r--r--src/gui/painting/qwindowsurface.cpp7
-rw-r--r--src/gui/styles/gtksymbols.cpp76
-rw-r--r--src/gui/styles/gtksymbols_p.h11
-rw-r--r--src/gui/styles/qgtkstyle.cpp130
-rw-r--r--src/gui/styles/qmacstyle_mac.mm34
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp52
-rw-r--r--src/gui/styles/qwindowsmobilestyle.cpp3
-rw-r--r--src/gui/styles/qwindowsvistastyle.cpp23
-rw-r--r--src/gui/styles/qwindowsvistastyle_p.h1
-rw-r--r--src/gui/styles/qwindowsxpstyle.cpp4
-rw-r--r--src/gui/text/qcssparser.cpp5
-rw-r--r--src/gui/text/qfont.cpp3
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp66
-rw-r--r--src/gui/text/qfontengine_mac.mm31
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontengine_win.cpp3
-rw-r--r--src/gui/text/qtextdocument.h1
-rw-r--r--src/gui/text/qtextdocument_p.cpp1
-rw-r--r--src/gui/text/qtexthtmlparser.cpp8
-rw-r--r--src/gui/text/qtextlist.cpp7
-rw-r--r--src/gui/text/qtextobject.cpp8
-rw-r--r--src/gui/text/qtextobject_p.h15
-rw-r--r--src/gui/text/qtexttable.cpp2
-rw-r--r--src/gui/text/qtexttable_p.h2
-rw-r--r--src/gui/util/qcompleter.cpp11
-rw-r--r--src/gui/util/qdesktopservices.cpp16
-rw-r--r--src/gui/widgets/qabstractbutton.cpp9
-rw-r--r--src/gui/widgets/qabstractbutton.h3
-rw-r--r--src/gui/widgets/qcocoamenu_mac.mm45
-rw-r--r--src/gui/widgets/qcombobox.cpp28
-rw-r--r--src/gui/widgets/qcombobox_p.h2
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp3
-rw-r--r--src/gui/widgets/qdockarealayout.cpp2
-rw-r--r--src/gui/widgets/qdockwidget.cpp19
-rw-r--r--src/gui/widgets/qmaccocoaviewcontainer_mac.mm22
-rw-r--r--src/gui/widgets/qmacnativewidget_mac.mm22
-rw-r--r--src/gui/widgets/qmainwindow.cpp2
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp3
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm44
-rw-r--r--src/gui/widgets/qmenu.cpp7
-rw-r--r--src/gui/widgets/qscrollbar.cpp33
-rw-r--r--src/gui/widgets/qtabbar.cpp90
-rw-r--r--src/gui/widgets/qtabbar_p.h33
-rw-r--r--src/gui/widgets/qtextedit.cpp8
-rw-r--r--src/gui/widgets/qtoolbar.cpp11
-rw-r--r--src/network/access/access.pri6
-rw-r--r--src/network/access/qhttp.cpp6
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp1119
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h243
-rw-r--r--src/network/access/qhttpnetworkheader.cpp123
-rw-r--r--src/network/access/qhttpnetworkheader_p.h111
-rw-r--r--src/network/access/qhttpnetworkreply.cpp663
-rw-r--r--src/network/access/qhttpnetworkreply_p.h224
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp261
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h144
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp36
-rw-r--r--src/network/access/qnetworkcookie.cpp466
-rw-r--r--src/network/access/qnetworkdiskcache.cpp3
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp44
-rw-r--r--src/network/kernel/qauthenticator.cpp2
-rw-r--r--src/network/kernel/qhostaddress.cpp2
-rw-r--r--src/network/kernel/qhostaddress.h1
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp6
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp5
-rw-r--r--src/network/socket/qabstractsocket.cpp4
-rw-r--r--src/network/socket/qlocalsocket_p.h1
-rw-r--r--src/network/socket/qlocalsocket_unix.cpp28
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp39
-rw-r--r--src/opengl/opengl.pro10
-rw-r--r--src/opengl/qgl.cpp8
-rw-r--r--src/opengl/qgl_cl_p.h2
-rw-r--r--src/opengl/qgl_mac.mm30
-rw-r--r--src/opengl/qgl_p.h1
-rw-r--r--src/opengl/qglframebufferobject.cpp4
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp8
-rw-r--r--src/opengl/qglpixelbuffer_mac.mm6
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp2
-rw-r--r--src/opengl/qpaintengine_opengl.cpp50
-rw-r--r--src/opengl/qwindowsurface_gl.cpp9
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro2
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp61
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h32
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp529
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp396
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h7
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp515
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h50
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp123
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbsurface.h13
-rw-r--r--src/plugins/gfxdrivers/powervr/README3
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp2
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp6
-rw-r--r--src/qt3support/itemviews/q3listview.cpp3
-rw-r--r--src/qt3support/text/q3richtext.cpp3
-rw-r--r--src/script/qscriptengine.cpp3
-rw-r--r--src/scripttools/debugging/qscriptbreakpointswidget.cpp8
-rw-r--r--src/scripttools/debugging/qscriptcompletiontask.cpp8
-rw-r--r--src/scripttools/debugging/qscriptdebugger.cpp6
-rw-r--r--src/scripttools/debugging/qscriptdebuggeragent.cpp19
-rw-r--r--src/scripttools/debugging/qscriptdebuggeragent_p.h3
-rw-r--r--src/scripttools/debugging/qscriptdebuggeragent_p_p.h6
-rw-r--r--src/scripttools/debugging/qscriptdebuggerbackend.cpp2
-rw-r--r--src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp4
-rw-r--r--src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp5
-rw-r--r--src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp8
-rw-r--r--src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp18
-rw-r--r--src/scripttools/debugging/qscriptedit.cpp10
-rw-r--r--src/scripttools/debugging/qscriptenginedebugger.h4
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp116
-rw-r--r--src/sql/drivers/db2/qsql_db2.h2
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp16
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp19
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.h3
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp119
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp136
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.h4
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp38
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp16
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp25
-rw-r--r--src/sql/drivers/tds/qsql_tds.cpp21
-rw-r--r--src/sql/kernel/qsqldriver.cpp140
-rw-r--r--src/sql/kernel/qsqldriver.h6
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp73
-rw-r--r--src/sql/models/qsqltablemodel.cpp20
-rw-r--r--src/svg/qsvggenerator.cpp29
-rw-r--r--src/svg/qsvghandler.cpp18
-rw-r--r--src/svg/qsvgstyle.cpp11
-rw-r--r--src/svg/qsvgstyle_p.h11
-rwxr-xr-xsrc/tools/moc/util/generate.sh4
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp131
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.h5
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp16
-rw-r--r--tests/arthur/common/paintcommands.cpp19
-rw-r--r--tests/arthur/common/qengines.cpp4
-rw-r--r--tests/arthur/data/qps/primitives.qps19
-rw-r--r--tests/auto/auto.pro4
-rw-r--r--tests/auto/bic/tst_bic.cpp19
-rw-r--r--tests/auto/collections/tst_collections.cpp38
-rw-r--r--tests/auto/compilerwarnings/tst_compilerwarnings.cpp2
-rw-r--r--tests/auto/mediaobject/tst_mediaobject.cpp20
-rw-r--r--tests/auto/moc/forgotten-qinterface.h2
-rw-r--r--tests/auto/moc/tst_moc.cpp84
-rw-r--r--tests/auto/q3accel/tst_q3accel.cpp86
-rw-r--r--tests/auto/q3cstring/tst_q3cstring.cpp86
-rw-r--r--tests/auto/q3header/tst_q3header.cpp4
-rw-r--r--tests/auto/q3ptrlist/tst_q3ptrlist.cpp13
-rw-r--r--tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp24
-rw-r--r--tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp12
-rw-r--r--tests/auto/q3table/tst_q3table.cpp1
-rw-r--r--tests/auto/q3textedit/tst_q3textedit.cpp2
-rw-r--r--tests/auto/q3textstream/tst_q3textstream.cpp10
-rw-r--r--tests/auto/q3timeedit/tst_q3timeedit.cpp4
-rw-r--r--tests/auto/q3valuelist/tst_q3valuelist.cpp6
-rw-r--r--tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp5
-rw-r--r--tests/auto/qabstractitemview/tst_qabstractitemview.cpp68
-rw-r--r--tests/auto/qabstractslider/tst_qabstractslider.cpp4
-rw-r--r--tests/auto/qaccessibility/tst_qaccessibility.cpp525
-rw-r--r--tests/auto/qalgorithms/tst_qalgorithms.cpp8
-rw-r--r--tests/auto/qbitarray/tst_qbitarray.cpp163
-rw-r--r--tests/auto/qbuttongroup/tst_qbuttongroup.cpp19
-rw-r--r--tests/auto/qcache/tst_qcache.cpp14
-rw-r--r--tests/auto/qcheckbox/tst_qcheckbox.cpp6
-rw-r--r--tests/auto/qcolordialog/tst_qcolordialog.cpp2
-rw-r--r--tests/auto/qcombobox/tst_qcombobox.cpp125
-rw-r--r--tests/auto/qcommandlinkbutton/tst_qcommandlinkbutton.cpp4
-rw-r--r--tests/auto/qcompleter/tst_qcompleter.cpp91
-rw-r--r--tests/auto/qcssparser/tst_cssparser.cpp10
-rw-r--r--tests/auto/qdatastream/tst_qdatastream.cpp4
-rw-r--r--tests/auto/qdate/tst_qdate.cpp21
-rw-r--r--tests/auto/qdatetime/tst_qdatetime.cpp15
-rw-r--r--tests/auto/qdesktopservices/tst_qdesktopservices.cpp5
-rw-r--r--tests/auto/qdialog/tst_qdialog.cpp21
-rw-r--r--tests/auto/qdir/tst_qdir.cpp4
-rw-r--r--tests/auto/qdirmodel/tst_qdirmodel.cpp2
-rw-r--r--tests/auto/qdockwidget/tst_qdockwidget.cpp15
-rw-r--r--tests/auto/qfile/rename-fallback.qrc (renamed from util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/QRC File.pbfiletemplate/resource.qrc)4
-rw-r--r--tests/auto/qfile/test/test.pro2
-rw-r--r--tests/auto/qfile/tst_qfile.cpp78
-rw-r--r--tests/auto/qfiledialog/tst_qfiledialog.cpp75
-rw-r--r--tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp6
-rw-r--r--tests/auto/qfont/tst_qfont.cpp3
-rw-r--r--tests/auto/qfontdatabase/tst_qfontdatabase.cpp2
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp168
-rw-r--r--tests/auto/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp6
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp21
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp31
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp66
-rw-r--r--tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp64
-rw-r--r--tests/auto/qhash/tst_qhash.cpp25
-rw-r--r--tests/auto/qhostinfo/tst_qhostinfo.cpp2
-rw-r--r--tests/auto/qhttp/tst_qhttp.cpp2
-rw-r--r--tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp2
-rw-r--r--tests/auto/qicoimageformat/tst_qticoimageformat.cpp35
-rw-r--r--tests/auto/qicon/tst_qicon.cpp2
-rw-r--r--tests/auto/qimage/tst_qimage.cpp5
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp27
-rw-r--r--tests/auto/qiodevice/tst_qiodevice.cpp6
-rw-r--r--tests/auto/qitemdelegate/tst_qitemdelegate.cpp1
-rw-r--r--tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp4
-rw-r--r--tests/auto/qitemmodel/modelstotest.cpp9
-rw-r--r--tests/auto/qitemview/tst_qitemview.cpp20
-rw-r--r--tests/auto/qkeysequence/tst_qkeysequence.cpp8
-rw-r--r--tests/auto/qlabel/tst_qlabel.cpp2
-rw-r--r--tests/auto/qlibrary/tst_qlibrary.cpp11
-rw-r--r--tests/auto/qline/tst_qline.cpp8
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp4
-rw-r--r--tests/auto/qlistview/tst_qlistview.cpp10
-rw-r--r--tests/auto/qlocale/tst_qlocale.cpp11
-rw-r--r--tests/auto/qmainwindow/tst_qmainwindow.cpp10
-rw-r--r--tests/auto/qmake/qmake.pro2
-rw-r--r--tests/auto/qmake/testcompiler.cpp311
-rw-r--r--tests/auto/qmake/testcompiler.h49
-rw-r--r--tests/auto/qmake/testdata/bundle-spaces/bundle-spaces.pro13
-rw-r--r--tests/auto/qmake/testdata/bundle-spaces/existing file (renamed from util/scripts/mac-binary/install/xcode/.build_separate)0
-rw-r--r--tests/auto/qmake/testdata/bundle-spaces/main.cpp0
-rw-r--r--tests/auto/qmake/testdata/bundle-spaces/some-file (renamed from tests/auto/qdir/testdir/dir/Makefile)0
-rw-r--r--tests/auto/qmake/testdata/functions/functions.pro14
-rw-r--r--tests/auto/qmake/testdata/shadow_files_build/README2
-rw-r--r--tests/auto/qmake/tst_qmake.cpp84
-rw-r--r--tests/auto/qmap/tst_qmap.cpp10
-rw-r--r--tests/auto/qmenu/tst_qmenu.cpp34
-rw-r--r--tests/auto/qmenubar/tst_qmenubar.cpp37
-rw-r--r--tests/auto/qmetaobject/tst_qmetaobject.cpp4
-rw-r--r--tests/auto/qmetatype/tst_qmetatype.cpp2
-rw-r--r--tests/auto/qmovie/tst_qmovie.cpp5
-rw-r--r--tests/auto/qmutexlocker/tst_qmutexlocker.cpp4
-rw-r--r--tests/auto/qnativesocketengine/tst_qnativesocketengine.cpp6
-rw-r--r--tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp295
-rw-r--r--tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp6
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp4
-rw-r--r--tests/auto/qobject/tst_qobject.cpp6
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp112
-rw-r--r--tests/auto/qpainterpath/tst_qpainterpath.cpp5
-rw-r--r--tests/auto/qpicture/tst_qpicture.cpp2
-rw-r--r--tests/auto/qpixmap/tst_qpixmap.cpp16
-rw-r--r--tests/auto/qprinter/tst_qprinter.cpp20
-rw-r--r--tests/auto/qprocess/tst_qprocess.cpp28
-rw-r--r--tests/auto/qpushbutton/tst_qpushbutton.cpp4
-rw-r--r--tests/auto/qreadlocker/tst_qreadlocker.cpp4
-rw-r--r--tests/auto/qreadwritelock/tst_qreadwritelock.cpp8
-rw-r--r--tests/auto/qrect/tst_qrect.cpp40
-rw-r--r--tests/auto/qregexp/tst_qregexp.cpp18
-rw-r--r--tests/auto/qregion/tst_qregion.cpp13
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp28
-rw-r--r--tests/auto/qset/tst_qset.cpp8
-rw-r--r--tests/auto/qsettings/tst_qsettings.cpp14
-rw-r--r--tests/auto/qsizef/tst_qsizef.cpp23
-rw-r--r--tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp251
-rw-r--r--tests/auto/qsqldatabase/tst_databases.h40
-rw-r--r--tests/auto/qsqldatabase/tst_qsqldatabase.cpp243
-rw-r--r--tests/auto/qsqldriver/qsqldriver.pro16
-rw-r--r--tests/auto/qsqldriver/tst_qsqldriver.cpp218
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp190
-rw-r--r--tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp22
-rw-r--r--tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp455
-rw-r--r--tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp178
-rw-r--r--tests/auto/qsqlthread/tst_qsqlthread.cpp12
-rw-r--r--tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp52
-rw-r--r--tests/auto/qstring/tst_qstring.cpp4
-rw-r--r--tests/auto/qstyle/tst_qstyle.cpp7
-rw-r--r--tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp23
-rw-r--r--tests/auto/qsvgdevice/tst_qsvgdevice.cpp10
-rw-r--r--tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp5
-rw-r--r--tests/auto/qtcpsocket/tst_qtcpsocket.cpp12
-rw-r--r--tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp33
-rw-r--r--tests/auto/qtextcodec/test/test.pro1
-rw-r--r--tests/auto/qtextcursor/tst_qtextcursor.cpp10
-rw-r--r--tests/auto/qtextdocument/tst_qtextdocument.cpp81
-rw-r--r--tests/auto/qtextdocumentfragment/tst_qtextdocumentfragment.cpp15
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp3
-rw-r--r--tests/auto/qtextobject/tst_qtextobject.cpp19
-rw-r--r--tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp2
-rw-r--r--tests/auto/qtextstream/tst_qtextstream.cpp8
-rw-r--r--tests/auto/qthread/tst_qthread.cpp5
-rw-r--r--tests/auto/qtime/tst_qtime.cpp14
-rw-r--r--tests/auto/qtimeline/tst_qtimeline.cpp6
-rw-r--r--tests/auto/qtimer/tst_qtimer.cpp95
-rw-r--r--tests/auto/qtranslator/qtranslator.pro2
-rw-r--r--tests/auto/qtreeview/tst_qtreeview.cpp113
-rw-r--r--tests/auto/qtreewidget/tst_qtreewidget.cpp9
-rw-r--r--tests/auto/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp14
-rw-r--r--tests/auto/qudpsocket/tst_qudpsocket.cpp4
-rw-r--r--tests/auto/qurl/tst_qurl.cpp8
-rw-r--r--tests/auto/qvariant/tst_qvariant.cpp4
-rw-r--r--tests/auto/qwaitcondition/tst_qwaitcondition.cpp14
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp37
-rw-r--r--tests/auto/qwizard/tst_qwizard.cpp36
-rw-r--r--tests/auto/qwmatrix/tst_qwmatrix.cpp17
-rw-r--r--tests/auto/qwritelocker/tst_qwritelocker.cpp4
-rw-r--r--tests/auto/rcc/tst_rcc.cpp15
-rw-r--r--tests/auto/selftests/alive/alive.pro1
-rw-r--r--tests/auto/selftests/assert/assert.pro1
-rw-r--r--tests/auto/selftests/benchlibcallgrind/benchlibcallgrind.pro1
-rw-r--r--tests/auto/selftests/benchlibeventcounter/benchlibeventcounter.pro1
-rw-r--r--tests/auto/selftests/benchliboptions/benchliboptions.pro1
-rw-r--r--tests/auto/selftests/benchlibtickcounter/benchlibtickcounter.pro1
-rw-r--r--tests/auto/selftests/benchlibwalltime/benchlibwalltime.pro1
-rw-r--r--tests/auto/selftests/cmptest/cmptest.pro1
-rw-r--r--tests/auto/selftests/commandlinedata/commandlinedata.pro1
-rw-r--r--tests/auto/selftests/crashes/crashes.pro1
-rw-r--r--tests/auto/selftests/datatable/datatable.pro1
-rw-r--r--tests/auto/selftests/datetime/datetime.pro1
-rw-r--r--tests/auto/selftests/differentexec/differentexec.pro1
-rw-r--r--tests/auto/selftests/exception/exception.pro1
-rw-r--r--tests/auto/selftests/expectfail/expectfail.pro1
-rw-r--r--tests/auto/selftests/failinit/failinit.pro1
-rw-r--r--tests/auto/selftests/failinitdata/failinitdata.pro1
-rw-r--r--tests/auto/selftests/fetchbogus/fetchbogus.pro1
-rw-r--r--tests/auto/selftests/globaldata/globaldata.pro1
-rw-r--r--tests/auto/selftests/maxwarnings/maxwarnings.pro1
-rw-r--r--tests/auto/selftests/multiexec/multiexec.pro1
-rw-r--r--tests/auto/selftests/qexecstringlist/qexecstringlist.pro1
-rw-r--r--tests/auto/selftests/singleskip/singleskip.pro1
-rw-r--r--tests/auto/selftests/skip/skip.pro1
-rw-r--r--tests/auto/selftests/skipglobal/skipglobal.pro1
-rw-r--r--tests/auto/selftests/skipinit/skipinit.pro1
-rw-r--r--tests/auto/selftests/skipinitdata/skipinitdata.pro1
-rw-r--r--tests/auto/selftests/sleep/sleep.pro1
-rw-r--r--tests/auto/selftests/strcmp/strcmp.pro1
-rw-r--r--tests/auto/selftests/subtest/subtest.pro1
-rw-r--r--tests/auto/selftests/tst_selftests.cpp4
-rwxr-xr-xtests/auto/selftests/updateBaselines.sh34
-rw-r--r--tests/auto/selftests/waitwithoutgui/waitwithoutgui.pro1
-rw-r--r--tests/auto/selftests/warnings/warnings.pro1
-rw-r--r--tests/benchmarks/qgraphicswidget/qgraphicswidget.pro6
-rw-r--r--tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp60
-rw-r--r--tests/benchmarks/qimagereader/tst_qimagereader.cpp2
-rw-r--r--tests/benchmarks/qobject/main.cpp14
-rw-r--r--tests/benchmarks/qpainter/tst_qpainter.cpp6
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene.cpp114
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene_p.h15
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp408
-rw-r--r--tools/assistant/tools/assistant/contentwindow.cpp60
-rw-r--r--tools/assistant/tools/assistant/contentwindow.h2
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qdocconf4
-rw-r--r--tools/assistant/tools/assistant/helpviewer.cpp83
-rw-r--r--tools/assistant/tools/assistant/helpviewer.h1
-rw-r--r--tools/assistant/tools/assistant/indexwindow.cpp63
-rw-r--r--tools/assistant/tools/assistant/indexwindow.h2
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp259
-rw-r--r--tools/assistant/tools/assistant/mainwindow.h8
-rw-r--r--tools/checksdk/main.cpp12
-rw-r--r--tools/configure/configureapp.cpp21
-rw-r--r--tools/configure/tools.cpp83
-rw-r--r--tools/configure/tools.h41
-rw-r--r--tools/designer/src/components/objectinspector/objectinspectormodel.cpp13
-rw-r--r--tools/designer/src/components/propertyeditor/designerpropertymanager.cpp2
-rw-r--r--tools/designer/src/lib/shared/actioneditor.cpp8
-rw-r--r--tools/designer/src/lib/shared/actionrepository.cpp17
-rw-r--r--tools/designer/src/lib/shared/actionrepository_p.h7
-rw-r--r--tools/designer/src/lib/shared/newactiondialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/newactiondialog_p.h2
-rw-r--r--tools/designer/src/lib/shared/plugindialog_p.h11
-rw-r--r--tools/designer/src/lib/shared/qdesigner_utils.cpp2
-rw-r--r--tools/designer/src/lib/shared/textpropertyeditor.cpp1
-rw-r--r--tools/designer/src/lib/uilib/resourcebuilder.cpp16
-rw-r--r--tools/linguist/lconvert/main.cpp2
-rw-r--r--tools/linguist/linguist/formpreviewview.cpp2
-rw-r--r--tools/linguist/linguist/mainwindow.cpp4
-rw-r--r--tools/linguist/linguist/messageeditor.cpp4
-rw-r--r--tools/linguist/linguist/messagemodel.cpp39
-rw-r--r--tools/linguist/linguist/messagemodel.h2
-rw-r--r--tools/linguist/linguist/phrase.cpp2
-rw-r--r--tools/linguist/linguist/phraseview.cpp2
-rw-r--r--tools/linguist/linguist/translationsettingsdialog.h2
-rw-r--r--tools/linguist/lrelease/main.cpp15
-rw-r--r--tools/linguist/lupdate/main.cpp3
-rw-r--r--tools/linguist/shared/cpp.cpp28
-rw-r--r--tools/linguist/shared/numerus.cpp2
-rw-r--r--tools/linguist/shared/po.cpp2
-rw-r--r--tools/linguist/shared/profileevaluator.cpp34
-rw-r--r--tools/linguist/shared/qm.cpp300
-rw-r--r--tools/linguist/shared/qph.cpp43
-rw-r--r--tools/linguist/shared/qscript.cpp2
-rw-r--r--tools/linguist/shared/qscript.g2
-rw-r--r--tools/linguist/shared/translator.cpp75
-rw-r--r--tools/linguist/shared/translator.h8
-rw-r--r--tools/linguist/shared/translatormessage.cpp4
-rw-r--r--tools/linguist/shared/translatormessage.h31
-rw-r--r--tools/linguist/shared/translatortools.cpp4
-rw-r--r--tools/linguist/shared/ts.cpp204
-rw-r--r--tools/linguist/shared/ts.dtd93
-rw-r--r--tools/linguist/shared/ui.cpp32
-rw-r--r--tools/linguist/shared/xliff.cpp2
-rw-r--r--tools/macdeployqt/macdeployqt/main.cpp22
-rw-r--r--tools/qdoc3/atom.cpp6
-rw-r--r--tools/qdoc3/atom.h4
-rw-r--r--tools/qdoc3/codeparser.cpp41
-rw-r--r--tools/qdoc3/cppcodeparser.cpp12
-rw-r--r--tools/qdoc3/doc.cpp256
-rw-r--r--tools/qdoc3/generator.cpp362
-rw-r--r--tools/qdoc3/generator.h95
-rw-r--r--tools/qdoc3/htmlgenerator.cpp166
-rw-r--r--tools/qdoc3/pagegenerator.cpp4
-rw-r--r--tools/qdoc3/test/classic.css8
-rw-r--r--tools/qdoc3/test/macros.qdocconf2
-rw-r--r--tools/qdoc3/test/qt-api-only.qdocconf2
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf6
-rw-r--r--tools/qdoc3/test/qt.qdocconf2
-rw-r--r--tools/qvfb/qvfb.cpp10
-rw-r--r--tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp4
-rw-r--r--tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h4
-rw-r--r--tools/shared/qtpropertybrowser/qteditorfactory.cpp4
-rw-r--r--tools/shared/qtpropertybrowser/qteditorfactory.h4
-rw-r--r--tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp4
-rw-r--r--tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h4
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.cpp4
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.h6
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp7
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h4
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertymanager.cpp27
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertymanager.h4
-rw-r--r--tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp8
-rw-r--r--tools/shared/qtpropertybrowser/qttreepropertybrowser.h4
-rw-r--r--tools/shared/qtpropertybrowser/qtvariantproperty.cpp8
-rw-r--r--tools/shared/qtpropertybrowser/qtvariantproperty.h4
-rwxr-xr-xutil/scripts/mac-binary/doit.sh24
-rw-r--r--util/scripts/mac-binary/install/debuglibraries/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/debuglibraries/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/debuglibraries/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/debuglibraries/Resources/debuglibraries.info17
-rwxr-xr-xutil/scripts/mac-binary/install/debuglibraries/Resources/postflight58
-rwxr-xr-xutil/scripts/mac-binary/install/debuglibraries/create_package.sh73
-rw-r--r--util/scripts/mac-binary/install/docs/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/docs/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/docs/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/docs/Resources/docs.info17
-rwxr-xr-xutil/scripts/mac-binary/install/docs/Resources/postflight16
-rwxr-xr-xutil/scripts/mac-binary/install/docs/create_package.sh35
-rw-r--r--util/scripts/mac-binary/install/examples/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/examples/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/examples/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/examples/Resources/examples.info17
-rw-r--r--util/scripts/mac-binary/install/examples/Resources/postflight31
-rwxr-xr-xutil/scripts/mac-binary/install/examples/create_package.sh148
-rw-r--r--util/scripts/mac-binary/install/headers/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/headers/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/headers/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/headers/Resources/headers.info17
-rwxr-xr-xutil/scripts/mac-binary/install/headers/Resources/postflight61
-rwxr-xr-xutil/scripts/mac-binary/install/headers/create_package.sh41
-rw-r--r--util/scripts/mac-binary/install/libraries/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/libraries/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/libraries/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/libraries/Resources/libraries.info17
-rwxr-xr-xutil/scripts/mac-binary/install/libraries/Resources/postflight76
-rwxr-xr-xutil/scripts/mac-binary/install/libraries/create_package.sh48
-rwxr-xr-xutil/scripts/mac-binary/install/libraries/fix_config_paths.pl60
-rwxr-xr-xutil/scripts/mac-binary/install/libraries/fix_prl_paths.pl17
-rw-r--r--util/scripts/mac-binary/install/plugins/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/plugins/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/plugins/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/plugins/Resources/plugins.info17
-rwxr-xr-xutil/scripts/mac-binary/install/plugins/Resources/postflight5
-rwxr-xr-xutil/scripts/mac-binary/install/plugins/create_package.sh31
-rw-r--r--util/scripts/mac-binary/install/tools/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/tools/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/tools/Resources/Readme.rtf7
-rwxr-xr-xutil/scripts/mac-binary/install/tools/Resources/postflight40
-rw-r--r--util/scripts/mac-binary/install/tools/Resources/tools.info17
-rwxr-xr-xutil/scripts/mac-binary/install/tools/create_package.sh142
-rw-r--r--util/scripts/mac-binary/install/translations/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/translations/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/translations/Resources/Readme.rtf7
-rwxr-xr-xutil/scripts/mac-binary/install/translations/Resources/postflight5
-rw-r--r--util/scripts/mac-binary/install/translations/Resources/translations.info17
-rw-r--r--util/scripts/mac-binary/install/translations/create_package.sh35
-rw-r--r--util/scripts/mac-binary/install/xcode/.gitattributes1
-rw-r--r--util/scripts/mac-binary/install/xcode/Info.plist40
-rw-r--r--util/scripts/mac-binary/install/xcode/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/install/xcode/Resources/Readme.rtf7
-rw-r--r--util/scripts/mac-binary/install/xcode/Resources/xcode.info17
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/create_package.sh46
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/do_translate.sh9
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/fake_package.sh49
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/scripts/get_file_list.applescript31
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/scripts/get_mocs.sh144
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/scripts/make_moc.sh98
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/scripts/make_rcc.sh45
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/scripts/make_uic.sh43
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/CustomDataViews/QtDataFormatters.bundle/Contents/Info.plist26
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/templates/CustomDataViews/QtDataFormatters.bundle/Contents/MacOS/build_bundle.sh20
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/CustomDataViews/QtDataFormatters.bundle/Contents/MacOS/bundle.cpp129
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/CustomDataViews/QtDataFormatters.bundle/Contents/Resources/CustomDataViews.plist48
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/CustomDataViews/QtDataFormatters.bundle/Contents/version.plist16
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/TemplateInfo.plist5
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/Header File.pbfiletemplate/TemplateInfo.plist4
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/Header File.pbfiletemplate/header.h51
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/QRC File.pbfiletemplate/TemplateInfo.plist4
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/UI File.pbfiletemplate/TemplateInfo.plist4
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/UI File.pbfiletemplate/class.ui16
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/Info.plist24
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/QtApp.mocs1
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/QtApp.pbproj/TemplateInfo.plist11
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/QtApp.pbproj/project.pbxproj377
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/version.plist16
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/templates/Scripts/999-Qt/10-aboutQt.sh23
-rwxr-xr-xutil/scripts/mac-binary/install/xcode/integration/templates/Scripts/999-Qt/20-getMocs.sh12
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Scripts/999-Qt/menuIcon.tiffbin1738 -> 0 bytes-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Specifications/qt.pbfilespec41
-rw-r--r--util/scripts/mac-binary/install/xcode/integration/templates/Specifications/qt.pblangspec84
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InfoPlist.stringsbin334 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane.nib/classes.nib43
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane.nib/info.nib23
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane.nib/keyedobjects.nib3688
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane~.nib/classes.nib42
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane~.nib/info.nib23
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/InstallerPane~.nib/keyedobjects.nib2942
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/English.lproj/Localizable.stringsbin154 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/InstallerPane/Info.plist30
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerPane.xcodeproj/default.pbxuser238
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerPane.xcodeproj/project.pbxproj381
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerPanePane.h68
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerPanePane.mm250
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerPane_Prefix.pch8
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerSecionSection.mm46
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/InstallerSections.plist16
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/helpfulfunc.mm88
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/keydec.cpp323
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/keydec.h197
-rw-r--r--util/scripts/mac-binary/package/InstallerPane/version.plist14
-rw-r--r--util/scripts/mac-binary/package/MetaPackage/Info.plist30
-rw-r--r--util/scripts/mac-binary/package/MetaPackage/PkgInfo1
-rw-r--r--util/scripts/mac-binary/package/MetaPackage/Resources/Description.plist14
-rw-r--r--util/scripts/mac-binary/package/MetaPackage/Resources/Qt.info16
-rwxr-xr-xutil/scripts/mac-binary/package/Resources/InstallationCheck96
-rw-r--r--util/scripts/mac-binary/package/Resources/InstallationCheck.stringsbin1688 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/Resources/background.jpgbin16423 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/Welcome-commercial.rtf25
-rw-r--r--util/scripts/mac-binary/package/Welcome-eval.rtf28
-rw-r--r--util/scripts/mac-binary/package/Welcome-opensource.rtf28
-rw-r--r--util/scripts/mac-binary/package/backgrounds/DiskImage-Commercial.pngbin8323 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/backgrounds/DiskImage-Eval.pngbin8334 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/backgrounds/DiskImage-Opensource.pngbin8503 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/backgrounds/DriveIcon.icnsbin58112 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/make-model-ds_store.applescript41
-rwxr-xr-xutil/scripts/mac-binary/package/mkcommercialpackage24
-rwxr-xr-xutil/scripts/mac-binary/package/mkpackage842
-rw-r--r--util/scripts/mac-binary/package/model-DS_Storebin12292 -> 0 bytes-rwxr-xr-xutil/scripts/mac-binary/package/model-DS_Store-4.0.0bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.0.1bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.0bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.1bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.2bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.3bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.4bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.5bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.1.6bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.0bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.0-rc1bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.1bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.2bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.3bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.4bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.2.5bin12293 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.0bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.1bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.2bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.3bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.4bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.3.5bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.0bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.0-rc1bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.1bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.2bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.3bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.4bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.4.5bin12292 -> 0 bytes-rw-r--r--util/scripts/mac-binary/package/model-DS_Store-4.5.0bin12292 -> 0 bytes-rwxr-xr-xutil/scripts/mac-binary/package/opensourceStuff/InstallationCheck15
-rw-r--r--util/scripts/mac-binary/package/opensourceStuff/InstallationCheck.stringsbin180 -> 0 bytes-rwxr-xr-xutil/scripts/mac-binary/package/uninstall-qt.py154
-rwxr-xr-xutil/scripts/make_qfeatures_dot_h118
-rwxr-xr-xutil/scripts/win-binary/batch/build.bat121
-rwxr-xr-xutil/scripts/win-binary/batch/copy.bat91
-rwxr-xr-xutil/scripts/win-binary/batch/delete.bat41
-rwxr-xr-xutil/scripts/win-binary/batch/env.bat101
-rwxr-xr-xutil/scripts/win-binary/batch/extract.bat47
-rwxr-xr-xutil/scripts/win-binary/batch/installer.bat227
-rwxr-xr-xutil/scripts/win-binary/batch/log.bat18
-rwxr-xr-xutil/scripts/win-binary/batch/toupper.bat29
-rw-r--r--util/scripts/win-binary/config/addin.conf42
-rw-r--r--util/scripts/win-binary/config/addin7x.conf48
-rw-r--r--util/scripts/win-binary/config/config.aeryn2
-rw-r--r--util/scripts/win-binary/config/config.alessandro6411
-rw-r--r--util/scripts/win-binary/config/config.chiana1
-rw-r--r--util/scripts/win-binary/config/config.default17
-rw-r--r--util/scripts/win-binary/config/config.innsikt1
-rw-r--r--util/scripts/win-binary/config/config.kepler14
-rw-r--r--util/scripts/win-binary/config/config.planck17
-rw-r--r--util/scripts/win-binary/config/config.radeberger17
-rw-r--r--util/scripts/win-binary/config/config.samarin1
-rw-r--r--util/scripts/win-binary/config/eclipse.conf20
-rw-r--r--util/scripts/win-binary/config/mingw-opensource.conf95
-rw-r--r--util/scripts/win-binary/config/qsa.conf34
-rw-r--r--util/scripts/win-binary/config/qsa_eval.conf36
-rw-r--r--util/scripts/win-binary/config/qsa_gpl.conf34
-rw-r--r--util/scripts/win-binary/config/qtjambi-commercial.conf33
-rw-r--r--util/scripts/win-binary/config/qtjambi-eval.conf34
-rw-r--r--util/scripts/win-binary/config/vc60-commercial.conf110
-rw-r--r--util/scripts/win-binary/config/vc60-eval.conf133
-rw-r--r--util/scripts/win-binary/config/vs2003-commercial-vsip.conf131
-rw-r--r--util/scripts/win-binary/config/vs2003-commercial.conf110
-rw-r--r--util/scripts/win-binary/config/vs2003-demo.conf58
-rw-r--r--util/scripts/win-binary/config/vs2003-eval.conf124
-rw-r--r--util/scripts/win-binary/config/vs2005-ce-commercial.conf165
-rw-r--r--util/scripts/win-binary/config/vs2005-ce-eval.conf202
-rw-r--r--util/scripts/win-binary/config/vs2005-commercial-vsip.conf131
-rw-r--r--util/scripts/win-binary/config/vs2005-commercial.conf113
-rw-r--r--util/scripts/win-binary/config/vs2005-eval.conf127
-rw-r--r--util/scripts/win-binary/config/vs2005-qtdemo.conf115
-rw-r--r--util/scripts/win-binary/config/vs2008-ce-commercial.conf97
-rw-r--r--util/scripts/win-binary/config/vs2008-ce-eval.conf202
-rw-r--r--util/scripts/win-binary/config/vs2008-commercial-vsip.conf131
-rw-r--r--util/scripts/win-binary/config/vs2008-commercial.conf113
-rw-r--r--util/scripts/win-binary/config/vs2008-eval.conf127
-rw-r--r--util/scripts/win-binary/config/vsip.conf41
-rwxr-xr-xutil/scripts/win-binary/doit/doit_2003.bat13
-rwxr-xr-xutil/scripts/win-binary/doit/doit_2005.bat13
-rwxr-xr-xutil/scripts/win-binary/doit/doit_2008.bat12
-rwxr-xr-xutil/scripts/win-binary/doit/doit_gcc.bat9
-rwxr-xr-xutil/scripts/win-binary/doit/doit_vc60.bat12
-rw-r--r--util/scripts/win-binary/doit/doit_wince_2005.bat13
-rwxr-xr-xutil/scripts/win-binary/doit/doit_wince_2008.bat11
-rwxr-xr-xutil/scripts/win-binary/iwmake.bat85
-rw-r--r--util/scripts/win-binary/nsis/confirmpage.ini19
-rw-r--r--util/scripts/win-binary/nsis/eclipse.ini60
-rw-r--r--util/scripts/win-binary/nsis/envpage.ini36
-rw-r--r--util/scripts/win-binary/nsis/gwdownload.ini78
-rw-r--r--util/scripts/win-binary/nsis/gwmirror.ini27
-rw-r--r--util/scripts/win-binary/nsis/images/install.icobin355574 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/images/qt-header.bmpbin25820 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/images/qt-wizard-clean.bmpbin154544 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/images/qt-wizard.bmpbin154544 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/includes/global.nsh204
-rw-r--r--util/scripts/win-binary/nsis/includes/help.nsh133
-rw-r--r--util/scripts/win-binary/nsis/includes/instdir.nsh214
-rw-r--r--util/scripts/win-binary/nsis/includes/list.nsh96
-rw-r--r--util/scripts/win-binary/nsis/includes/qtcommon.nsh547
-rw-r--r--util/scripts/win-binary/nsis/includes/qtdir.nsh120
-rw-r--r--util/scripts/win-binary/nsis/includes/qtenv.nsh350
-rw-r--r--util/scripts/win-binary/nsis/includes/regsvr.nsh59
-rw-r--r--util/scripts/win-binary/nsis/includes/system.nsh364
-rw-r--r--util/scripts/win-binary/nsis/includes/templates.nsh262
-rw-r--r--util/scripts/win-binary/nsis/includes/writeEnvStr.nsh138
-rw-r--r--util/scripts/win-binary/nsis/includes/writePathStr.nsh241
-rw-r--r--util/scripts/win-binary/nsis/installer.nsi524
-rw-r--r--util/scripts/win-binary/nsis/instdir.ini102
-rw-r--r--util/scripts/win-binary/nsis/license.ini70
-rw-r--r--util/scripts/win-binary/nsis/licensepage.ini48
-rw-r--r--util/scripts/win-binary/nsis/modules/addin60.nsh139
-rw-r--r--util/scripts/win-binary/nsis/modules/addin7x.nsh417
-rw-r--r--util/scripts/win-binary/nsis/modules/debugext.nsh669
-rw-r--r--util/scripts/win-binary/nsis/modules/eclipse.nsh398
-rw-r--r--util/scripts/win-binary/nsis/modules/environment.nsh176
-rw-r--r--util/scripts/win-binary/nsis/modules/evaluation.nsh116
-rw-r--r--util/scripts/win-binary/nsis/modules/help.nsh274
-rw-r--r--util/scripts/win-binary/nsis/modules/license.nsh377
-rw-r--r--util/scripts/win-binary/nsis/modules/mingw.nsh629
-rw-r--r--util/scripts/win-binary/nsis/modules/msvc.nsh439
-rw-r--r--util/scripts/win-binary/nsis/modules/opensource.nsh56
-rw-r--r--util/scripts/win-binary/nsis/modules/qsa.nsh255
-rw-r--r--util/scripts/win-binary/nsis/modules/qtdemo.nsh112
-rw-r--r--util/scripts/win-binary/nsis/modules/qtjambi.nsh98
-rw-r--r--util/scripts/win-binary/nsis/modules/qtjambieclipse.nsh223
-rw-r--r--util/scripts/win-binary/nsis/modules/registeruiext.nsh174
-rw-r--r--util/scripts/win-binary/nsis/modules/vsip.nsh1030
-rw-r--r--util/scripts/win-binary/nsis/opensource.ini38
-rw-r--r--util/scripts/win-binary/nsis/qsa.ini28
-rw-r--r--util/scripts/win-binary/nsis/qtdir.ini70
-rw-r--r--util/scripts/win-binary/nsis/qtjambieclipse.ini26
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/binpatch.cpp216
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/exdll.h137
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/licensefinder.cpp250
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/mingw.cpp156
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/mingw.h45
-rwxr-xr-xutil/scripts/win-binary/nsis/qtnsisext/qtlibspatcher.exebin77824 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/qtlibspatcher.vcproj206
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/qtlibspatchermain.cpp200
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/qtnsisext.cpp495
-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/qtnsisext.dllbin77824 -> 0 bytes-rw-r--r--util/scripts/win-binary/nsis/qtnsisext/qtnsisext.vcproj164
-rwxr-xr-xutil/webkit/mkdist-webkit37
971 files changed, 18765 insertions, 37275 deletions
diff --git a/.commit-template b/.commit-template
new file mode 100644
index 0000000..589ca89
--- /dev/null
+++ b/.commit-template
@@ -0,0 +1,10 @@
+# ===[ Subject ]==========[ one line, please wrap at 72 characters ]===|
+
+# ---[ Details ]---------[ remember extra blank line after subject ]---|
+
+# ---[ Fields ]-----------------[ uncomment and edit as applicable ]---|
+
+#Task-number:
+#Reviewed-by:
+
+# ==================================[ please wrap at 72 characters ]===|
diff --git a/FAQ b/FAQ.txt
index c243e5c..f20d10b 100644
--- a/FAQ
+++ b/FAQ.txt
@@ -1,4 +1,4 @@
-This is a list of Frequently Asked Questions regarding Qt Release 4.5.0.
+This is a list of Frequently Asked Questions regarding this Qt release.
Q: I'm using a Unix system and I downloaded the Zip package. However, when I try
to run the configure script, I get the following error message:
diff --git a/LGPL_EXCEPTION.TXT b/LGPL_EXCEPTION.txt
index 8d0f85e..8d0f85e 100644
--- a/LGPL_EXCEPTION.TXT
+++ b/LGPL_EXCEPTION.txt
diff --git a/config.tests/mac/defaultarch.test b/config.tests/mac/defaultarch.test
new file mode 100755
index 0000000..4502af7
--- /dev/null
+++ b/config.tests/mac/defaultarch.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+COMPILER=$1
+VERBOSE=$2
+WORKDIR=$3
+QT_MAC_DEFUALT_ARCH=
+
+touch defaultarch.c
+
+# compile something and run 'file' on it.
+if "$COMPILER" -c defaultarch.c 2>/dev/null 1>&2; then
+ FIlE_OUTPUT=`file defaultarch.o`
+ [ "$VERBOSE" = "yes" ] && echo "'file' reports compiler ($COMPILER) default architechture as: $FIlE_OUTPUT"
+
+fi
+rm -f defaultarch.c defaultarch.o
+
+# detect our known archs.
+if echo "$FIlE_OUTPUT" | grep '\<i386\>' > /dev/null 2>&1; then
+ QT_MAC_DEFUALT_ARCH=x86 # configure knows it as "x86" not "i386"
+fi
+if echo "$FIlE_OUTPUT" | grep '\<x86_64\>' > /dev/null 2>&1; then
+ QT_MAC_DEFUALT_ARCH=x86_64
+fi
+if echo "$FIlE_OUTPUT" | grep '\<ppc\>' > /dev/null 2>&1; then
+ QT_MAC_DEFUALT_ARCH=ppc
+fi
+if echo "$FIlE_OUTPUT" | grep '\<ppc64\>' > /dev/null 2>&1; then
+ QT_MAC_DEFUALT_ARCH=ppc64
+fi
+
+[ "$VERBOSE" = "yes" ] && echo "setting QT_MAC_DEFUALT_ARCH to \"$QT_MAC_DEFUALT_ARCH\""
+export QT_MAC_DEFUALT_ARCH
diff --git a/config.tests/unix/opengles1/opengles1.pro b/config.tests/unix/opengles1/opengles1.pro
index d800a5d..ad8dd31 100644
--- a/config.tests/unix/opengles1/opengles1.pro
+++ b/config.tests/unix/opengles1/opengles1.pro
@@ -6,4 +6,4 @@ for(p, QMAKE_LIBDIR_OPENGL) {
}
CONFIG -= qt
-LIBS += $$QMAKE_LIBS_OPENGL
+LIBS += $$QMAKE_LIBS_OPENGL_QT
diff --git a/config.tests/unix/opengles1cl/opengles1cl.pro b/config.tests/unix/opengles1cl/opengles1cl.pro
index c9addf9..415cdbb 100644
--- a/config.tests/unix/opengles1cl/opengles1cl.pro
+++ b/config.tests/unix/opengles1cl/opengles1cl.pro
@@ -6,4 +6,4 @@ for(p, QMAKE_LIBDIR_OPENGL) {
}
CONFIG -= qt
-LIBS += $$QMAKE_LIBS_OPENGL
+LIBS += $$QMAKE_LIBS_OPENGL_QT
diff --git a/config.tests/unix/opengles2/opengles2.pro b/config.tests/unix/opengles2/opengles2.pro
index 13f95a1..0dfae42 100644
--- a/config.tests/unix/opengles2/opengles2.pro
+++ b/config.tests/unix/opengles2/opengles2.pro
@@ -6,4 +6,4 @@ for(p, QMAKE_LIBDIR_OPENGL) {
}
CONFIG -= qt
-LIBS += $$QMAKE_LIBS_OPENGL
+LIBS += $$QMAKE_LIBS_OPENGL_QT
diff --git a/config.tests/x11/xlib/xlib.cpp b/config.tests/x11/xlib/xlib.cpp
new file mode 100644
index 0000000..8d25bf5
--- /dev/null
+++ b/config.tests/x11/xlib/xlib.cpp
@@ -0,0 +1,9 @@
+#include <X11/Xlib.h>
+
+int main(int, char **)
+{
+ Display *d = XOpenDisplay(NULL);
+ XCloseDisplay(d);
+ return 0;
+}
+
diff --git a/config.tests/x11/xlib/xlib.pro b/config.tests/x11/xlib/xlib.pro
new file mode 100644
index 0000000..658161e
--- /dev/null
+++ b/config.tests/x11/xlib/xlib.pro
@@ -0,0 +1,3 @@
+CONFIG += x11
+CONFIG -= qt
+SOURCES = xlib.cpp
diff --git a/configure b/configure
index 841f47d..9f2b28d 100755
--- a/configure
+++ b/configure
@@ -119,7 +119,13 @@ elif [ -f "$relpath"/src/gui/kernel/qapplication_qws.cpp ]; then
# ~ src/gui/base/qapplication_qws.cpp is present
# ~ this is the free or commercial edition
# ~ this is the internal edition and Qt Embedded is explicitly enabled
- PLATFORM_QWS=maybe
+ if [ -f "$relpath"/src/gui/kernel/qapplication_mac.mm ]; then
+ # This is a depot build, or an all-platforms package
+ PLATFORM_QWS=maybe
+ else
+ # This must be the embedded package, since the Qt/Mac source files are not present
+ PLATFORM_QWS=yes
+ fi
fi
#-----------------------------------------------------------------------------
@@ -199,10 +205,10 @@ earlyArgParse()
h|help|--help|-help)
if [ "$VAL" = "yes" ]; then
OPT_HELP="$VAL"
- COMMERCIAL_USER="yes" #doesn't matter we will display the help
+ COMMERCIAL_USER="no" #doesn't matter we will display the help
else
UNKNOWN_OPT=yes
- COMMERCIAL_USER="yes" #doesn't matter we will display the help
+ COMMERCIAL_USER="no" #doesn't matter we will display the help
fi
;;
--*)
@@ -518,9 +524,14 @@ fi
SYSTEM_VARIABLES="CC CXX CFLAGS CXXFLAGS LDFLAGS"
for varname in $SYSTEM_VARIABLES; do
+ qmakevarname="${varname}"
+ # use LDFLAGS for autoconf compat, but qmake uses QMAKE_LFLAGS
+ if [ "${varname}" = "LDFLAGS" ]; then
+ qmakevarname="LFLAGS"
+ fi
cmd=`echo \
'if [ -n "\$'${varname}'" ]; then
- QMakeVar set QMAKE_'${varname}' "\$'${varname}'"
+ QMakeVar set QMAKE_'${qmakevarname}' "\$'${varname}'"
fi'`
eval "$cmd"
done
@@ -2090,7 +2101,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then
fi
# symlink files from src/gui/embedded neccessary to build qvfb
-if [ "$CFG_DEV" = "yes" -o "$Edition" = "Qtopia" ]; then
+if [ "$CFG_DEV" = "yes" ]; then
for f in qvfbhdr.h qlock_p.h qlock.cpp qwssignalhandler_p.h qwssignalhandler.cpp; do
dest="${relpath}/tools/qvfb/${f}"
rm -f "$dest"
@@ -2687,6 +2698,21 @@ if [ "$QT_CROSS_COMPILE" = "yes" ]; then
fi
fi
+# check -arch arguments for validity.
+if [ "$PLATFORM_MAC" = "yes" ]; then
+ ALLOWED="x86 ppc x86_64 ppc64 i386"
+ for i in $CFG_MAC_ARCHS
+ do
+ if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then
+ echo "Unknown architecture: \"$i\". Supported architectures: x86[i386] ppc x86_64 ppc64";
+ exit 2;
+ fi
+ done
+
+# replace "i386" with "x86" to support configuring with -arch i386 as an alias for x86.
+ CFG_MAC_ARCHS="${CFG_MAC_ARCHS/i386/x86}"
+fi
+
# find the default framework value
if [ "$PLATFORM_MAC" = "yes" ] && [ "$PLATFORM" != "macx-xlc" ]; then
if [ "$CFG_FRAMEWORK" = "auto" ]; then
@@ -3654,39 +3680,7 @@ echo
echo "This is the $Platform ${EditionString} Edition."
echo
-if [ "$Edition" = "Qtopia" ]; then
- TheLicense=`head -n 1 "$relpath/LICENSE.Qtopia"`
- while true; do
- if [ "$OPT_CONFIRM_LICENSE" = "yes" -o "$CFG_NOKIA" = "yes" ]; then
- echo "You have already accepted the terms of the $TheLicense license."
- acceptance=yes
- else
- echo "You are licensed to use this software under the terms of"
- echo "the $TheLicense"
- echo
- echo "Type '?' to read the $TheLicense"
- echo "Type 'yes' to accept this license offer."
- echo "Type 'no' to decline this license offer."
- echo
- if echo '\c' | grep '\c' >/dev/null; then
- echo -n "Do you accept the terms of the license? "
- else
- echo "Do you accept the terms of the license? \c"
- fi
- read acceptance
- fi
- echo
- if [ "$acceptance" = "yes" ]; then
- break
- elif [ "$acceptance" = "no" ] ;then
- echo "You are not licensed to use this software."
- echo
- exit 0
- elif [ "$acceptance" = "?" ]; then
- more "$relpath/LICENSE.Qtopia"
- fi
- done
-elif [ "$Edition" = "NokiaInternalBuild" ]; then
+if [ "$Edition" = "NokiaInternalBuild" ]; then
echo "Detected -nokia-developer option"
echo "Nokia employees and agents are allowed to use this software under"
echo "the authority of Nokia Corporation and/or its subsidiary(-ies)"
@@ -4742,6 +4736,14 @@ if [ "$PLATFORM_X11" = "yes" ]; then
X11TESTS_FLAGS="$X11TESTS_FLAGS -fpermissive"
fi
+ # Check we actually have X11 :-)
+ if ! "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then
+ echo "Basic XLib functionality test failed!"
+ echo " You might need to modify the include and library search paths by editing"
+ echo " QMAKE_INCDIR_X11 and QMAKE_LIBDIR_X11 in ${XQMAKESPEC}."
+ exit 1
+ fi
+
# auto-detect OpenGL support (es1 = OpenGL ES 1.x Common, es1cl = ES 1.x common lite, es2 = OpenGL ES 2.x)
if [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/opengl "OpenGL" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then
@@ -5503,6 +5505,22 @@ if [ "$CFG_MAC_DWARF2" = "yes" ]; then
QT_CONFIG="$QT_CONFIG dwarf2"
fi
+# Set the default arch. Select 32-bit/carbon if nothing else has
+# been specified on the configure line.
+if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" == "" ]; then
+ source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests"
+
+ if [ "$QT_MAC_DEFUALT_ARCH" == "x86_64" ]; then
+ CFG_MAC_ARCHS=" x86"
+ elif [ "$QT_MAC_DEFUALT_ARCH" == "ppc64" ]; then
+ CFG_MAC_ARCHS=" ppc"
+ else
+ CFG_MAC_ARCHS=" $QT_MAC_DEFUALT_ARCH"
+ fi
+
+ [ "$OPT_VERBOSE" == "yes" ] && echo "Setting Mac architechture to$CFG_MAC_ARCHS."
+fi
+
# enable cocoa and/or carbon on Mac
if [ "$CFG_MAC_COCOA" = "yes" ]; then
# -cocoa on the command line disables carbon completely (i.e. use cocoa for 32-bit as well)
@@ -6173,13 +6191,31 @@ rm -f .options
BUILD_OPTIONS="$BUILD_CONFIG $BUILD_OPTIONS"
# extract the operating system from the XPLATFORM
TARGET_OPERATING_SYSTEM=`echo $XPLATFORM | cut -f 2- -d/ | cut -f -1 -d-`
+
# when cross-compiling, don't include build-host information (build key is target specific)
QT_BUILD_KEY="$CFG_USER_BUILD_KEY $CFG_ARCH $TARGET_OPERATING_SYSTEM $COMPILER $BUILD_OPTIONS"
+if [ -n "$QT_NAMESPACE" ]; then
+ QT_BUILD_KEY="$QT_BUILD_KEY $QT_NAMESPACE"
+fi
+MAC_NEED_TWO_BUILD_KEYS="no"
+if [ "$PLATFORM_MAC" = "yes" -a "$CFG_MAC_COCOA" = "yes" ]; then
+ QT_BUILD_KEY_CARBON=$QT_BUILD_KEY
+ TARGET_OPERATING_SYSTEM="$TARGET_OPERATING_SYSTEM-cocoa"
+ QT_BUILD_KEY_COCOA="$CFG_USER_BUILD_KEY $CFG_ARCH $TARGET_OPERATING_SYSTEM $COMPILER $BUILD_OPTIONS"
+ if [ "$CFG_MAC_CARBON" = "no" ]; then
+ QT_BUILD_KEY=$QT_BUILD_KEY_COCOA
+ else
+ MAC_NEED_TWO_BUILD_KEYS="yes"
+ fi
+fi
# don't break loading plugins build with an older version of Qt
QT_BUILD_KEY_COMPAT=
if [ "$QT_CROSS_COMPILE" = "no" ]; then
# previous versions of Qt used a build key built from the uname
QT_BUILD_KEY_COMPAT="$CFG_USER_BUILD_KEY $UNAME_MACHINE $UNAME_SYSTEM $COMPILER $BUILD_OPTIONS"
+ if [ -n "$QT_NAMESPACE" ]; then
+ QT_BUILD_KEY_COMPAT="$QT_BUILD_KEY_COMPAT $QT_NAMESPACE"
+ fi
fi
# strip out leading/trailing/extra whitespace
QT_BUILD_KEY=`echo $QT_BUILD_KEY | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"`
@@ -6200,6 +6236,7 @@ full)
echo "#endif" >>"$tmpconfig"
;;
esac
+
cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
/* Qt Edition */
@@ -6210,9 +6247,19 @@ cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
/* Machine byte-order */
#define Q_BIG_ENDIAN 4321
#define Q_LITTLE_ENDIAN 1234
+EOF
-#define QT_BUILD_KEY "$QT_BUILD_KEY"
+if [ "$MAC_NEED_TWO_BUILD_KEYS" = "no" ]; then
+ echo "#define QT_BUILD_KEY \"$QT_BUILD_KEY\"" \
+ >> "$outpath/src/corelib/global/qconfig.h.new"
+else
+ cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
+
+#define QT_BUILD_KEY_CARBON "$QT_BUILD_KEY_CARBON"
+#define QT_BUILD_KEY_COCOA "$QT_BUILD_KEY_COCOA"
EOF
+fi
+
if [ -n "$QT_BUILD_KEY_COMPAT" ]; then
echo "#define QT_BUILD_KEY_COMPAT \"$QT_BUILD_KEY_COMPAT\"" \
>> "$outpath/src/corelib/global/qconfig.h.new"
diff --git a/configure.exe b/configure.exe
index 54e8a60..ff71f08 100644
--- a/configure.exe
+++ b/configure.exe
Binary files differ
diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp
index ed2fc76..dd8766f 100644
--- a/demos/embeddeddialogs/customproxy.cpp
+++ b/demos/embeddeddialogs/customproxy.cpp
@@ -44,7 +44,7 @@
#include <QtGui>
CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags)
- : QGraphicsProxyWidget(parent, wFlags), popupShown(false)
+ : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0)
{
timeLine = new QTimeLine(250, this);
connect(timeLine, SIGNAL(valueChanged(qreal)),
@@ -112,13 +112,17 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
- QGraphicsItem *item = qVariantValue<QGraphicsItem *>(value);
if (change == ItemChildAddedChange) {
- item->setCacheMode(ItemCoordinateCache);
- item->installSceneEventFilter(this);
- } else {
- item->removeSceneEventFilter(this);
+ currentPopup = qVariantValue<QGraphicsItem *>(value);
+ currentPopup->setCacheMode(ItemCoordinateCache);
+ if (scene())
+ currentPopup->installSceneEventFilter(this);
+ } else if (scene()) {
+ currentPopup->removeSceneEventFilter(this);
+ currentPopup = 0;
}
+ } else if (currentPopup && change == ItemSceneHasChanged) {
+ currentPopup->installSceneEventFilter(this);
}
return QGraphicsProxyWidget::itemChange(change, value);
}
diff --git a/demos/embeddeddialogs/customproxy.h b/demos/embeddeddialogs/customproxy.h
index 0a5fbaf..d324426 100644
--- a/demos/embeddeddialogs/customproxy.h
+++ b/demos/embeddeddialogs/customproxy.h
@@ -70,6 +70,7 @@ private slots:
private:
QTimeLine *timeLine;
bool popupShown;
+ QGraphicsItem *currentPopup;
};
#endif
diff --git a/demos/qtdemo/colors.cpp b/demos/qtdemo/colors.cpp
index 18343cb..41bbfb3 100644
--- a/demos/qtdemo/colors.cpp
+++ b/demos/qtdemo/colors.cpp
@@ -278,6 +278,9 @@ void Colors::parseArgs(int argc, char *argv[])
+ "[-low] [-ticker-letters<int>] [-ticker-speed<float>] [-no-ticker-morph] "
+ "[-ticker-morph-speed<float>] [-ticker-text<string>]");
exit(0);
+ } else{
+ QMessageBox::warning(0, "QtDemo", QString("Unrecognized argument:\n") + s);
+ exit(0);
}
}
diff --git a/demos/qtdemo/menumanager.cpp b/demos/qtdemo/menumanager.cpp
index bfa2e3f..a9e9b4b 100644
--- a/demos/qtdemo/menumanager.cpp
+++ b/demos/qtdemo/menumanager.cpp
@@ -184,7 +184,6 @@ void MenuManager::itemSelected(int userCode, const QString &menuName)
this->tickerInAnim->startDelay = 2000;
this->ticker->useGuideQt();
this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY);
- this->window->switchTimerOnOff(true);
}
break;
case MENU1:
@@ -220,7 +219,6 @@ void MenuManager::itemSelected(int userCode, const QString &menuName)
this->score->queueMovie(this->currentInfo + " -buttons", Score::NEW_ANIMATION_ONLY);
if (!Colors::noTicker){
this->score->queueMovie("ticker -out", Score::NEW_ANIMATION_ONLY);
- this->window->switchTimerOnOff(false);
}
break;
case UP:{
@@ -257,7 +255,6 @@ void MenuManager::itemSelected(int userCode, const QString &menuName)
this->ticker->doIntroTransitions = false;
this->tickerInAnim->startDelay = 500;
this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY);
- this->window->switchTimerOnOff(true);
}
} else if (this->currentMenuCode != ROOT)
itemSelected(ROOT, Colors::rootMenuName);
diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml
index df2d93b..03b59f3 100644
--- a/demos/qtdemo/xml/examples.xml
+++ b/demos/qtdemo/xml/examples.xml
@@ -137,6 +137,7 @@
<example filename="fontsampler" name="Font Sampler" />
<example filename="imagecomposition" name="Image Composition" />
<example filename="painterpaths" name="Painter Paths" />
+ <example filename="svggenerator" name="SVG Generator" />
<example filename="svgviewer" name="SVG Viewer" />
<example filename="transformations" name="Transformations" />
</category>
diff --git a/dist/README b/dist/README
index 110be1c..38b3a1c 100644
--- a/dist/README
+++ b/dist/README
@@ -114,7 +114,7 @@ HOW TO REPORT A BUG
If you think you have found a bug in Qt, we would like to hear about
it so that we can fix it. Before reporting a bug, please check
http://qtsoftware.com/developer/faqs/ and
-http://qtsoftware.com/products/appdev/platform/platforms/ to see if the to see if
+http://qtsoftware.com/products/appdev/platform/platforms/ to see if
the issue is already known.
Always include the following information in your bug report: the name
diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1
new file mode 100644
index 0000000..c9e689f
--- /dev/null
+++ b/dist/changes-4.5.1
@@ -0,0 +1,574 @@
+Qt 4.5.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 4.5.0. For more details,
+refer to the online documentation included in this distribution. The
+documentation is also available online:
+
+ http://doc.trolltech.com/4.5
+
+The Qt version 4.5 series is binary compatible with the 4.4.x series.
+Applications compiled for 4.4 will continue to run with 4.5.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Task Tracker:
+
+ http://www.qtsoftware.com/developer/task-tracker
+
+Each of these identifiers can be entered in the task tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+General Improvements
+--------------------
+
+- Documentation and Examples
+ * Added printing feature for the Spreadsheet demo.
+ * [245675] Clarified the differences between QItemDelegate and
+ QStyledItemDelegate.
+ * [248752] Marked QPrintDialog::printer(), setPrinter() and addButton()
+ as Unix only functions, part of Qt3Support.
+
+- Embedded Dialogs demo
+ * [246517] Fixed warnings and bugs in hover handling on Mac OS X
+
+
+Optimizations
+-------------
+
+- Graphics View Framework has been optimized in several areas
+ * Improved the performance of QGraphicsItem::clipPath().
+ * Improved the performance of QGraphicsItem::setPos().
+ * Improved the performance of QGraphicsItem::effectiveOpacity().
+ * Improved the performance of QGrahicsScene::items(*).
+ * Improved handling of updates.
+ * Reduced the number of floating point operations.
+ * Reduced QVariant overhead.
+
+Third party components
+----------------------
+
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+- QAbstractItemModel
+ * Clarified some warning messages printed if the model is invalid.
+
+- QAbstractEventDispatcher
+ * [248805] Duplicate timerids could occur if a timer is running while the
+ QObject is moved to another thread, stopping timers from working.
+
+- QAbstractSocket
+ * [192037] Emit the disconnected signal only if we were connected before.
+
+- QAccessible
+ * [221731] Fixed a bug where the accessibility plugin could crash if
+ there was an "&" at the end or spin forever if a label had a sequence of
+ "&&".
+ * [241161] Fixed a bug in browsing menus with the keyboard.
+
+- QAtomicInt
+ * [216492] Fixed compilation on 64-bit PowerPC machines with gcc 4.3.
+
+- QAuthenticator
+ * [237979] Fixed implementation of md5-sess.
+
+- QByteArray
+ * [246233] QByteArray::fromHex() fails with input of size 1.
+
+- QColorDialog
+ * [247349] Fixed a bug causing the wrong alpha value to be returned.
+
+- QCombobox
+ * [248094] Fixed scrollbar from appearing when not required.
+
+- QCompleter
+ * [246056] Fixed an assertion failure in setCompletionPrefix().
+ * [250064] Fixed a regression in focus policy propagation.
+
+- QtConcurrent
+ * [244718] Reduced the number of calls to QThread::idealThreadCount().
+
+- QDirIterator
+ * [247645] Fixed a bug that may loose all cached data inside QFileInfo.
+
+- QFile
+ * [244485] Renaming a file does not change QFile::fileName().
+ * [244500] QFile::rename() does not always return false when the method
+ fails
+
+- QFileInfo
+ * [205244] Return valid file info also for relative UNC paths.
+
+- QFileDialog
+ * [221323] Fixed a bug in QFileDialog's programmatical file selection.
+ * [248332] QFileDialog is slow after visiting a large directory.
+ * [250194] Fixed an issue with QFileDialog and QSortFilterProxyModel
+ index mapping.
+
+- QGLFramebufferObject
+ * Framebuffer object extension resolution now works with OpenGL/ES 2.0.
+
+- QGraphicsItem
+ * Fixed a slow down regression in QGraphicsItem::ItemCoordinateCache.
+ * [247890] Cached QGraphicsItems are not updated if update() is called
+ when they are hidden.
+ * [250272] Fixed a crash that could occur when an item is deleted but
+ it does not get removed from the sceneeventfilters.
+
+- QGraphicsGridLayout
+ * [242472] Fixed a bug where the calculation of the maximum width of a
+ column was incorrect.
+
+- QGraphicsScene
+ * [243707] Fixed a crash when adding a child before a parent to the
+ scene.
+
+- QGraphicsView
+ * [245766] Rubber Band drag mode does not update correctly when
+ scrolling.
+
+- QGraphicsWidget
+ * [246215] Fixed a regression where we could cache the wrong size hint
+ because we called the virtual sizeHint() from the constructor.
+
+- QHttp
+ * Compile fixes for QT_BEGIN_NAMESPACE being in the wrong place in some
+ private headers.
+ * [208445] Cancel request upon receiving unknown authentication method.
+
+- QHostAddress
+ * [247330] Fixed compilation on MinGW by adding a missing QPair include.
+
+- QLocalSocket
+ * Fixed a bug that would cause QLocalSocket to disconnect 30 seconds
+ after a succesful delayed connection on UNIX.
+
+- QMacStyle
+ * Adjusted the opacity value for popups.
+ * [248769] Fixed a regression where QMacStyle would only draw tabs when
+ passed a QStyleOptionTabV3.
+
+- QMainWindow
+ * [248048] Fixed a regression that would cause tooltips to disappear when
+ using the unified toolbar.
+
+- QMetaType
+ * [248890] The detailed description of QMetaType no longer contradicts
+ the documentation of QMetaType::type()
+
+- QMutex
+ * Fixed a performance regression for contended mutexes as reported on the
+ qt4-preview-feedback list.
+
+- QPainter
+ * Compile fixes for OpenGL paint engine on OpenGL/ES 1.1 CommonLite and
+ OpenGL/ES 1.0.
+ * [246573] Fixed a very slow stroking of paths in the X11 paint engine.
+ * [247083] Fixed the scale applied to antialiased cosmetic pens in X11
+ paint engine.
+ * [247492] Fixed a rendering bug in the raster paint engine causing
+ * [247505] Fixed missing fills of rectangles with negative width/height
+ in raster paint engine.
+ one-pixel offset when drawing premultiplied ARGB32 images on RGB16
+ images.
+ * [249490] Fixed one-pixel offset between stroke and fills of ellipses in
+ the X11 paint engine.
+ * [249628] Fixed a crash in OpenGL paint engine when filling using
+ Qt::NoBrush.
+
+
+- QPixmap
+ * [249175] Fixed QPixmap::fromImage() of monochrome images to result in
+ black/white pixels and not transparent/white pixels.
+
+- QProcess
+ * [247865] Fixed a crash when calling QProcess::start() and
+ startDetached() with an empty program string.
+
+- QScrollBar
+ * [247985] Stylesheet: added the feature to style scrollbar menus.
+
+- QSharedPointer
+ * [246843] Fixed a crash caused by using QSharedPointer in global statics.
+
+- QSortFilterProxyModel
+ * [247867] Properly sort when calling appendRows().
+ * [248868] Re-sort when the model is reset if dynamicSort is enabled.
+ * [248868] Fixed QSortFilterProxyModel::sort() if dynamicSort was disabled.
+
+- QSSlSocket
+ * [245668] Set also protocol, verifyMode and verifyDepth in
+ setSslConfiguration().
+
+- QString
+ * [249517] Fixed a regression in replace(int, int, QChar) when the string
+ is empty.
+
+- QStyleSheetStyle
+ * Improved support for setting background and foreground roles in styles
+ such as the text color in a combo box popup on Mac and Cleanlooks, or
+ the background of QScrollBar.
+ * Fixed a crash that occured while styling the title bar of a QMdiArea.
+ * [188195] Fixed the background of QAbstractScrollArea losing its color
+ if styled with pseudo-class.
+ * [246542] Fixed a bug in QToolButton::hover{ color:.... }.
+
+- QThread
+ * [249997] Added documentation indicating that the priority set by the
+ programmer may be ignored, for example on Linux.
+
+- QTreeView
+ * Fixed a crash that may occur when events are processed immediately
+ after a QSortFilterProxyModel is invalidated.
+ * [246025] Fixed auto-expand that occured when quickly collapsing an item
+ after clicking on a child.
+ * [248163] Fixed a possible crash in the paintEvent() when spans are used.
+ * [248805] Calling QTreeView::sortByColumn() programmatically was not
+ working if manual sorting was disabled.
+
+- QWidget
+ * [250388] Fixed a potential crash in QWidget::scroll() when using the
+ raster graphics system.
+
+- QWidget
+ * [246852] Improved handling of WindowMaximizeButtonHint for widgets with
+ layouts.
+
+-QLocale
+ * String-to-number conversion functions will now ignore trailing and
+ leading whitespaces in all locales as documented.
+
+- QWizard
+ * [248107] Fixed a bug on Windows Vista causing the Back button to
+ connect to the back() signal twice.
+
+- Q3ListView
+ * [248689] Fixed a bug in Q3ListView that would not update under certain
+ conditions.
+
+- QtWebKit
+ * Fixed a bug in cookie handling (WebKit Bugzilla 24062, Benjamin Meyer).
+ * Fixed a bug in calling from JavaScript into NPAPI plugins on Windows.
+ * Fixed the updating state of WebActions (Erik Bunce)
+ * Fixed a bug in HTML 5 Canvas clearRect() (Dirk Schulze)
+ * Fixed the theming of text fields with KDE 4 Oxygen style (Zack Rusin)
+ * Fixed path fill styles (Zack Rusin)
+ * Fixed pre-edit text handling with input methods.
+ * [248643] Fixed compiling with the "-pedantic" compile option.
+
+- QSqlTableModel
+ * Made setTable() try and use the database's letter case (uppercase/
+ lowercase) of the given tablename.
+ * [189093] QSqlTableModel did not handle updates when one of the fields
+ had a NULL value.
+
+****************************************************************************
+* Database Drivers *
+****************************************************************************
+
+ * Fixed the DB2 driver returning a double field as empty.
+ * Fixed a memory leak in the DB2 driver.
+ * Fixed the DB2 driver not quoting table/field names properly.
+ * Fixed an issue with ODBC & FreeTDS not accepting quotes in statements.
+ * Fixed a bug in the sqlite2 driver not returning false on failing to
+ execute a statement.
+ * PrecisionPolicy now works in the oracle driver.
+ * Fixed a bug in the ODBC driver returning a list of tables when
+ requested.
+ * Fixed Interbase retrieving scale/precision information on numeric/
+ decimal fields.
+ * Stopped drivers from quoting again when escapeIdentifier is called
+ twice.
+ * Fixed a bug in the sqlite2 driver not quoting fields correctly.
+ * [232769] Fixed a memory overflow issue on bound out strings in ODBC
+ Driver
+ * [249059] Fixed a bug that handled QPSQL datetime/time fields with
+ negative timezone offsets incorrectly.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+Qt for Linux/X11
+----------------
+
+ * Ensured proper resetting for input contexts when switching between
+ multiple input context plugins.
+ * Input methods preedit strings are now reset properly when user switches
+ focus without commiting a string.
+ * Unicode conversion functions will handle Latin-1 character set only if
+ they are used before a QCoreApplication/QApplication is constructed.
+ * Improved handling of failed unicode conversion.
+ * Fixed clipboard handling when the user manually creates an instance of
+ the QDesktopWidget.
+ * [226048] Ensured that the QDesktopWidget::resized() signal is emitted
+ properly when a new screen appears or the screen geometry is changed
+ without affecting the whole desktop's geometry.
+ * [232632] Fixed a bug in reparenting widgets to a difference X11 screen.
+ * [241888] The background of the drag-n-drop cursor is now respected,
+ according to the stylesheet.
+ * [244337] Improved input method handling when a widget's native window
+ id is recreated.
+ * [244607] Current focus widget is properly set and input method is
+ properly initialized when showing a toplevel widget that accepts
+ keyboard input.
+
+- Phonon/GStreamer
+ * [233188] Fixed a problem where the seek slider reset to 0 while being
+ dragged.
+ * [244259] Fixed a problem where the backend failed to indicate an error
+ when the streaming failed.
+ * [246097] Added support for the MediaController interface to allow audio
+ CD playback.
+ * [246189] Fixed a problem where the backend failed to correctly escape
+ certain file names casuing playback to not start.
+
+
+- QGtkStyle
+ * The system palette is no longer strictly forced. Also improved behavior
+ related to system theme changes.
+ * Fixed palette and styling issues with the background color of combo box
+ popups.
+ * [238196] Allowed middle click to set scrollbar position, following GTK+
+ behavior.
+ * [239829] Disabled alt-key navigation for QGtkStyle following GTK+
+ behavior.
+ * [247653] Fixed a compilation issue on Solaris.
+ * [249363] QFrame is now styled as a GtkScrolledWindow.
+
+- Font rendering
+ * Improved performance of subpixel antialiased text rendering by using a
+ mask in the calls to XRender's text compositing function.
+ * [248387] Properly respect the font config LCD filter settings for
+ subpixel antialiased text rendering when Freetype's native subpixel
+ rendering is disabled.
+ * [248498] Fix garbled rendering of subpixel antialiased text when using
+ Freetype's native subpixel rendering for vertical subpixel layouts.
+ * [248644] Fall back to Qt's subpixel rendering if Freetype's subpixel
+ rendering was available at compile-time but not at run-time.
+
+- QEventDispatcherGlib
+ * Event posted to a thread before it is started are not processed until
+ others events are posted.
+
+- QWidget
+ * [213512] Fixed a bug that caused wrong clipping when using the
+ Qt::WA_PaintOutsidePaintEvent attribute.
+
+
+Qt for Windows
+--------------
+
+ * [240891] Corrected the focus behavior of native file dialogs, when an
+ application has multiple toplevel widgets.
+ * [243583] Improved drag-and-drop handling when switching mouse buttons
+ quickly.
+ * [244875] The system menu will now be shown for a fullscreen window.
+ * [245330] Fixed a bug that caused mouse inputs to be ignored on modal
+ dialogs, when shown from an ActiveQt control.
+ * [249576] Fixed a crash when using a combobox with Qt::NoFocus.
+
+
+- QCoreApplication
+ * [247401] Fixed a bug that caused a restarted timer to fire too early,
+ resulting in QtWebKit's Javascript consuming 100% CPU on Windows.
+- QWindowsXPStyle
+ * [248036] Fixed an issue where tool buttons were hovering incorrectly
+ when disabled.
+
+- QWidget
+ * [248391] Fixed a bug that made it impossible to dynamically switch from
+ QPainter-based graphics to native graphics API and back.
+
+
+Qt for Mac OS X
+---------------
+
+ * Fixed a crash when showing a widget that is a modal window but has no
+ parent.
+ * Added QSysInfo::MV_10_6 as an enum to test against.
+ * Various compile fixes for the preliminary supported Snow Leopard.
+ * The uninstall-qt.py script included in the binary package no longer
+ complains about removing itself multiple times.
+- * Improved the documentation for how qt_mac_set_dock_menu() works.
+ * Fixed an issue with the focus frame's transparency as it was difficult
+ to use the QWidget with stylesheets.
+ * [223525] Fixed a crash in the MacMainWindow Demo.
+ * [248803] Ensured that two dialogs shown at the same time will both not
+ have visible default buttons.
+
+- QDesktopWidget
+ * [244004] Properly support multiple screens with different sizes.
+
+- QDialog
+ * [195904] Parent dialog is displayed on top of its modal child.
+ * [218980] Modeless dialogs should be stacked above normal windows.
+ * [239155] QDialog(foo, Qt::Sheet) with QComboBox has non-native
+ behavior.
+
+- QFileDialog
+ * [219844] Fixed a crash caused by QFileDialog::getOpenFileName()'s
+ search buttons (native version).
+ * [225705] QFileDialog::getSaveFileName()'s filter does not display
+ correctly.
+
+- QMenu
+ * [228017] Ensured that QMenu closes when expanding a system menu.
+
+- QTestLib
+ * Activate the test application when launched from the command line.
+
+- Event system
+ * [210912] Fixed a bug where ShowEvent not sent when reshowing a window
+ after it was minimized.
+
+- macdeployqt
+ * The binary packages now include this tool.
+ * macdeployqt now runs 'strip' on the deployed binaries.
+ * Fixed an issue that prevented the QtSvg module from being deployed.
+
+- configure script
+ * Now supports "-arch i386" as an alias for "-arch x86".
+ * Detects invalid arch arguemnts and exits.
+
+- Cocoa port
+ * Fixed a bug where actions in the native menubar were not disabled
+ properly.
+ * Made shortcuts work properly when using the Dvorak-QWERTY+CMD keyboard
+ layout.
+ * Fixed a bug where dialogs were positioned in the wrong place on the
+ screen.
+ * The build-key for Cocoa was changed in the unlikely case that a plugin
+ may make assumptions on how Qt was built. All Cocoa plugins built
+ against Qt 4.5.0 will NOT work with Qt 4.5.1; we do not foresee
+ changing this again.
+ * Fixed a bug where some windows did not get activation when they
+ normally should.
+ * Fixed a bug where key events sent to popups were not propagated
+ onwards.
+ * QFileOpenEvents will no longer be sent for items passed via command
+ line.
+ * Various fixes for determining the metrics of text and the ability to
+ disable kerning.
+ * Modified the Colliding Mice Example to work better with coalesced
+ updates.
+ * Fixed a bug where the drag cursor was not updated when modifier keys
+ were used.
+ * [239043] Fixed a bug that caused QGraphicsProxyWidget to shrink when
+ moved.
+ * [244369] Window flags on Cocoa windows should look similar to the
+ Carbon ones.
+ * [247947] Fixed a crash in drag and drop.
+ * [248918] Fixed color matching for themed text items.
+ * The command + h shortcut is now enabled. (Hides the current window.)
+ * [249296] Fixed a bug where line edits on a second page of a stack
+ widget were not getting key events.
+
+Qt for Embedded Linux
+---------------------
+
+- * Various improvements to the Qt DirectFB plugin.
+ * Fixed recreation of temporary EGL surfaces in the PowerVR QScreen
+ driver.
+- * Document some necessary #define's for building the PowerVR QScreen
+ driver.
+
+Qt for Windows CE
+-----------------
+
+ * [246619] Fixed a tap and hold bug for QCheckbox.
+
+****************************************************************************
+* Compiler Specific Changes *
+****************************************************************************
+
+
+****************************************************************************
+* Tools *
+****************************************************************************
+
+- Build System
+
+- Assistant
+
+
+- Designer
+ * [245503] Fixed redundant backslashes in string property in the property
+ browser.
+ * [245961] Restricted objectname-validation to known object name
+ properties only.
+ * [247995] Fixed a crash occurring after layout operations that caused
+ an instance of QGridLayout or QFormLayout to shrink.
+ * [248000] Fixed a crash ocurring when re-layouting empty grid layouts.
+ * [249097] Fixed a crash related to undoing a QGridLayout re-layout
+ operation.
+
+- Linguist
+
+ - Linguist GUI
+
+ * [248076] Fixed a crash caused by opening files for which we have no
+ plural rules.
+ * [249519] Fixed a crash upon dropping text into a non-focused line
+ edit.
+
+ - Entire Linguist toolchain
+
+ * [244035] Fixed an infinite loop in PO writer.
+ * [247738] Improved handling of duplicated messages.
+ * [248849] Fixed the encoding in XLIFF writer.
+ * [249022] Fixed TS' and QM's handling of messages which appear in
+ multiple encodings.
+
+ - lupdate
+
+ * [248724] Fixed the encoding of messages from .ui files if CODECFORTR
+ is not utf8.
+ * [249633] Fixed the processing of C++ backslash line continuations.
+
+- rcc
+
+
+- moc
+ * [240368] moc parsing issue with "unsigned" subphrase
+
+- uic
+ * [244998] Fixed include file generation for phonon widgets.
+ * [248070] Fixed code generation for QStringList-type properties to use
+ encoding properly.
+ * [242447] Made uic generate class-specific code correctly in the case of
+ multiple levels of inheritance.
+
+- uic3
+
+
+- qmake
+ * On Mac OS, properly escape file names in QMAKE_BUNDLE_DATA.
+ * Fixed moc and uic features to make shadow builds work even if a
+ non-shadow build is present
+ * [201495] Comment processing in qmake prevented file from being moc'ed
+ * [248806] Ensured that the Xcode generator includes the right path to
+ frameworks.
+
+- configure
+
+
+- qtconfig
+
+
+- qt3to4
+
+
+****************************************************************************
+* Plugins *
+****************************************************************************
+
+
+****************************************************************************
+* Important Behavior Changes *
+****************************************************************************
+
diff --git a/doc/src/custom-types.qdoc b/doc/src/custom-types.qdoc
index bf5340e..81eecfc 100644
--- a/doc/src/custom-types.qdoc
+++ b/doc/src/custom-types.qdoc
@@ -56,9 +56,123 @@
Standard types such as QSize, QColor and QString can all be stored in QVariant objects,
used as the types of properties in QObject-based classes, and emitted in signal-slot
communication.
+
In this document, we take a custom type and describe how to integrate it into Qt's object
model so that it can be stored in the same way as standard Qt types. We then show how to
register the custom type to allow it to be used in signals and slots connections.
\section1 Creating a Custom Type
+
+ Before we begin, we need to ensure that the custom type we are creating meets all the
+ requirements imposed by QMetaType. In other words, it must provide:
+
+ \list
+ \o a public default constructor,
+ \o a public copy constructor, and
+ \o a public destructor.
+ \endlist
+
+ The following \c Message class definition includes these members:
+
+ \snippet examples/tools/customtype/message.h custom type definition
+
+ The class also provides a constructor for normal use and two public member functions
+ that are used to obtain the private data.
+
+ \section1 Declaring the Type with QMetaType
+
+ The \c Message class only needs a suitable implementation in order to be usable.
+ However, Qt's type system will not be able to understand how to store, retrieve
+ and serialize instances of this class without some assistance. For example, we
+ will be unable to store \c Message values in QVariant.
+
+ The class in Qt responsible for custom types is QMetaType. To make the type known
+ to this class, we invoke the Q_DECLARE_METATYPE() macro on the class in the header
+ file where it is defined:
+
+ \snippet examples/tools/customtype/message.h custom type meta-type declaration
+
+ This now makes it possible for \c Message values to be stored in QVariant objects
+ and retrieved later. See the \l{Custom Type Example} for code that demonstrates
+ this.
+
+ The Q_DECLARE_METATYPE() macro also makes it possible for these values to be used as
+ arguments to signals, but \e{only in direct signal-slot connections}.
+ To make the custom type generally usable with the signals and slots mechanism, we
+ need to perform some extra work.
+
+ \section1 Creating and Destroying Custom Objects
+
+ Although the declaration in the previous section makes the type available for use
+ in direct signal-slot connections, it cannot be used for queued signal-slot
+ connections, such as those that are made between objects in different threads.
+ This is because the meta-object system does not know how to handle creation and
+ destruction of objects of the custom type at run-time.
+
+ To enable creation of objects at run-time, call the qRegisterMetaType() template
+ function to register it with the meta-object system. This also makes the type
+ available for queued signal-slot communication as long as you call it before you
+ make the first connection that uses the type.
+
+ The \l{Queued Custom Type Example} declares a \c Block class which is registered
+ in the \c{main.cpp} file:
+
+ \snippet examples/threads/queuedcustomtype/main.cpp main start
+ \dots
+ \snippet examples/threads/queuedcustomtype/main.cpp register meta-type for queued communications
+ \dots
+ \snippet examples/threads/queuedcustomtype/main.cpp main finish
+
+ This type is later used in a signal-slot connection in the \c{window.cpp} file:
+
+ \snippet examples/threads/queuedcustomtype/window.cpp Window constructor start
+ \dots
+ \snippet examples/threads/queuedcustomtype/window.cpp connecting signal with custom type
+ \dots
+ \snippet examples/threads/queuedcustomtype/window.cpp Window constructor finish
+
+ If a type is used in a queued connection without being registered, a warning will be
+ printed at the console; for example:
+
+ \code
+ QObject::connect: Cannot queue arguments of type 'Block'
+ (Make sure 'Block' is registered using qRegisterMetaType().)
+ \endcode
+
+ \section1 Making the Type Printable
+
+ It is often quite useful to make a custom type printable for debugging purposes,
+ as in the following code:
+
+ \snippet examples/tools/customtype/main.cpp printing a custom type
+
+ This is achieved by creating a streaming operator for the type, which is often
+ defined in the header file for that type:
+
+ \snippet examples/tools/customtype/message.h custom type streaming operator
+
+ The implementation for the \c Message type in the \l{Custom Type Example}
+ goes to some effort to make the printable representation as readable as
+ possible:
+
+ \snippet examples/tools/customtype/message.cpp custom type streaming operator
+
+ The output sent to the debug stream can, of course, be made as simple or as
+ complicated as you like. Note that the value returned by this function is
+ the QDebug object itself, though this is often obtained by calling the
+ maybeSpace() member function of QDebug that pads out the stream with space
+ characters to make it more readable.
+
+ \section1 Further Reading
+
+ The Q_DECLARE_METATYPE() macro and qRegisterMetaType() function documentation
+ contain more detailed information about their uses and limitations.
+
+ The \l{Custom Type Example}{Custom Type},
+ \l{Custom Type Sending Example}{Custom Type Sending}
+ and \l{Queued Custom Type Example}{Queued Custom Type} examples show how to
+ implement a custom type with the features outlined in this document.
+
+ The \l{Debugging Techniques} document provides an overview of the debugging
+ mechanisms discussed above.
*/
diff --git a/doc/src/debug.qdoc b/doc/src/debug.qdoc
index cd9d8cb..da5a82f 100644
--- a/doc/src/debug.qdoc
+++ b/doc/src/debug.qdoc
@@ -200,7 +200,10 @@
between each item. Here is an example for a class that represents
a 2D coordinate.
- \snippet doc/src/snippets/qdebugsnippet.cpp 0
+ \snippet doc/src/snippets/qdebug/qdebugsnippet.cpp 0
+
+ Integration of custom types with Qt's meta-object system is covered
+ in more depth in the \l{Creating Custom Qt Types} document.
\section1 Debugging Macros
diff --git a/doc/src/deployment.qdoc b/doc/src/deployment.qdoc
index 496fe81..d9f7c1a 100644
--- a/doc/src/deployment.qdoc
+++ b/doc/src/deployment.qdoc
@@ -89,7 +89,8 @@
of Qt, you get Qt as a shared library.
The disadvantage with the shared library approach is that you
- will get more files to deploy.
+ will get more files to deploy. For more information, see
+ \l{sharedlibrary.html}{Creating Shared Libraries}.
\section1 Deploying Qt's Libraries
@@ -110,13 +111,14 @@
\o \l {QtNetwork}
\o \l {QtOpenGL}
\o \l {QtScript}
- \o \l {QtSql}
+ \o \l {QtScriptTools}
\row
+ \o \l {QtSql}
\o \l {QtSvg}
\o \l {QtWebKit}
\o \l {QtXml}
- \o \l {QtXmlPatterns}
\row
+ \o \l {QtXmlPatterns}
\o \l {Phonon Module}{Phonon}
\o \l {Qt3Support}
\endtable
@@ -177,11 +179,13 @@
Please see \l{QtWebKit Module#License Information}{the QtWebKit module
documentation} for more information.
- \row \o Phonon \o Phonon
+ \row \o \l{Phonon Module}{Phonon} \o Phonon
\o Phonon relies on the native multimedia engines on different platforms.
Phonon itself is licensed under the GNU LGPL version 2. Please see
\l{Phonon Module#License Information}{the Phonon module documentation}
- for more information.
+ for more information on licensing and the
+ \l{Phonon Overview#Backends}{Phonon Overview} for details of the backends
+ in use on different platforms.
\endtable
\section1 Platform-Specific Notes
@@ -878,30 +882,44 @@
HTML pages from the World Wide Web, you should include all text codec
plugins to support as many HTML encodings possible.
- The search path for Qt plugins (as well as a few other paths) is
- hard-coded into the QtCore library. By default, the first plugin
- search path will be hard-coded to be a \c plugins subdirectory of
- the Qt installation:
-
- \snippet doc/src/snippets/code/doc_src_deployment.qdoc 25
-
- Pre-determined paths like this one have certain disadvantages.
- For example, they may not exist on the target machine. For that
- reason you need to examine various alternatives to make sure that
- the Qt plugins are found:
+ The search path for Qt plugins is hard-coded into the QtCore library.
+ By default, the plugins subdirectory of the Qt installation is the first
+ plugin search path. However, pre-determined paths like the default one
+ have certain disadvantages. For example, they may not exist on the target
+ machine. For that reason, you need to examine various alternatives to make
+ sure that the Qt plugins are found:
\list
- \o \l{qt-conf.html}{Using \c qt.conf}. This is the recommended
- approach since it provides the most flexibility.
-
+ \o \l{qt-conf.html}{Using \c qt.conf}. This approach is the recommended
+ if you have executables in different places sharing the same plugins.
+
\o Using QApplication::addLibraryPath() or
- QApplication::setLibraryPaths().
+ QApplication::setLibraryPaths(). This approach is recommended if you only
+ have one executable that will use the plugin.
\o Using a third party installation utility to change the
hard-coded paths in the QtCore library.
\endlist
+
+ If you add a custom path using QApplication::addLibraryPath it could
+ look like this:
+
+ \snippet doc/src/snippets/code/doc_src_deployment.qdoc 54
+
+ Then qApp->libraryPaths() would return something like this:
+
+ "C:/customPath/plugins "
+ "C:/Qt/4.5.0/plugins"
+ "E:/myApplication/directory/"
+
+ The executable will look for the plugins in these directories and
+ the same order as the QStringList returned by qApp->libraryPaths().
+ The newly added path is prepended to the qApp->libraryPaths() which
+ means that it will be searched through first. However, if you use
+ qApp->setLibraryPaths(), you will be able to determend which paths
+ and in which order they will be searched.
The \l{How to Create Qt Plugins} document outlines the issues you
need to pay attention to when building and deploying plugins for
@@ -1105,7 +1123,7 @@
\snippet doc/src/snippets/code/doc_src_deployment.qdoc 38
For the Qt frameworks, the first line (i.e. \c
- {path/to/Qt/lib/QtGui.framework/Versions/4.0/QtGui (compatibility
+ {path/to/Qt/lib/QtGui.framework/Versions/4/QtGui (compatibility
version 4.0.0, current version 4.0.1)}) becomes the framework's
identification name which is used by the dynamic linker (\c dyld).
@@ -1448,4 +1466,11 @@
\o The accessibility plugin is always deployed.
\o Accessibility for Qt3Support is deployed if the application uses the Qt3Support module.
\endlist
+
+ macdeployqt supports the following options:
+ \list
+ \o -no-plugins: Skip plugin deployment
+ \o -dmg : Create a .dmg disk image
+ \o -no-strip : Don't run 'strip' on the binaries
+ \endlist
*/
diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc
index 768f476..e10a5be 100644
--- a/doc/src/designer-manual.qdoc
+++ b/doc/src/designer-manual.qdoc
@@ -128,6 +128,7 @@
\header
\i Widget Filter Box
\i Widget Morphing
+ \i Disambiguation Field
\row
\i \inlineimage designer-widget-filter.png
\i \inlineimage designer-widget-morph.png
@@ -1855,7 +1856,7 @@ pixmap property in the property editor.
\section2 The Direct Approach
- To demonstrate thow to use user interface (\c{.ui}) files straight from
+ To demonstrate how to use user interface (\c{.ui}) files straight from
\QD, we create a simple Calculator Form application. This is based on the
original \l{Calculator Form Example}{Calculator Form} example.
@@ -2294,7 +2295,7 @@ pixmap property in the property editor.
\image worldtimeclockplugin-example.png
- The \l QtDesigner module provides you with the ability to create cusom
+ The \l QtDesigner module provides you with the ability to create custom
widgets in \QD.
@@ -2442,6 +2443,10 @@ pixmap property in the property editor.
\target BuildingandInstallingthePlugin
\section1 Building and Installing the Plugin
+ \section2 A Simple Plugin
+
+ The \l{Custom Widget Plugin Example} demonstrates a simple \QD plugin.
+
The \c{.pro} file for a plugin must specify the headers and sources for
both the custom widget and the plugin interface. Typically, this file only
has to specify that the plugin's project is to be built as a library, but
@@ -2476,65 +2481,42 @@ pixmap property in the property editor.
See QCoreApplication::libraryPaths() for more information about customizing
paths for libraries and plugins with Qt applications.
-\omit
- \section1 Using Qt Script to Aid in Building Forms
-
- Starting with Qt 4.3, \c .ui files may contain
- \l{QtScript}{Qt Script} snippets that are executed by \l uic or QUiLoader
- when building forms.
+ \section2 Splitting up the Plugin
- The snippets are executed per widget. The snippet may modify properties
- or invoke slots on the widget.
+ In a real world scenario, you do not want to have dependencies of the
+ application making use of the custom widgets to the \QD headers and
+ libraries as introduced by the simple approach explained above.
- Special variables are used to access the widget:
+ There are two ways to resolve this:
- \table
- \header
- \o Name
- \o Value
- \row \o \c widget
- \o The widget being built.
- \row \o \c childWidgets
- \o An array containing the child widgets. This is useful
- for QDesignerContainerExtension subclasses.
- \endtable
+ \list
+ \i Create a \c{.pri} file that contains the headers sources and sources
+ of the custom widget:
- If scripts are present in an \c {uic}-generated form, the application
- must be configured with Qt Script support.
+ \code
+ INCLUDEPATH += $$PWD
+ HEADERS += $$PWD/analogclock.h
+ SOURCES += $$PWD/analogclock.cpp
+ \endcode
- \snippet doc/src/snippets/code/doc_src_designer-manual.qdoc 5
+ This file would then be included by the \c{.pro} file of the plugin and
+ the application:
- For security reasons, the execution of scripts is disabled
- by default in QUiLoader. You can enable it by
- calling the QUiLoader::setScriptingEnabled() method.
+ \code
+ include(customwidget.pri)
+ \endcode
- The resulting script snippet is concatenated from snippets occurring in
- several places:
+ Running \c{qmake -Wall} on the \c{.pro} files causes a warning to be
+ printed if an included \c{.pri} file cannot be found.
- \table
- \header
- \o Source
- \o Usage
- \row \o The \c codeTemplate() function of QDesignerCustomWidgetInterface
- \o Allows snippets to be run on a per-class basis; for example, to set up a
- container using the QDesignerContainerExtension.
- \row \o The \c script() method of QDesignerScriptExtension
- \o Allows snippets to be run on a per-widget basis; for example,
- to set up the internal state of a custom widget.
-
- Such an internal state might be, for example, the contents of
- a custom item view container widget, for which an editor
- is provided by an QDesignerTaskMenuExtension object.
-
- \row \o Snippets entered at run-time using the \gui{Change script...}
- option of the form's context menu
- \o Fast prototyping. To get an idea,
- drag a QLineEdit onto the form, enter the script
- \snippet doc/src/snippets/code/doc_src_designer-manual.qdoc 6
- and preview the form.
- \endtable
-\endomit
+ \i Create a standalone shared library containing the custom widgets only
+ as described in
+ \l{sharedlibrary.html}{Creating Shared Libraries}.
+ This library would then be used by the application as well as by the
+ \QD plugin. Care must be taken to ensure that the plugin can locate
+ the library at run-time.
+ \endlist
\section1 Related Examples
diff --git a/doc/src/diagrams/qtransform-representation.sk b/doc/src/diagrams/qtransform-representation.sk
new file mode 100644
index 0000000..17dcbfe
--- /dev/null
+++ b/doc/src/diagrams/qtransform-representation.sk
@@ -0,0 +1,103 @@
+##Sketch 1 2
+document()
+layout('A4',0)
+layer('Layer 1',1,1,0,0,(0,0,0))
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,190,760)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,190,695)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,190,630)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,320,760)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,320,695)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,320,630)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,255,760)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,255,695)
+lp((0,0,1))
+lw(2)
+r(65,0,0,-65,255,630)
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m33',(329.16,589.968))
+G()
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('dy',(274.828,577.768))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m32',(264.16,602.768))
+G_()
+G()
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m31',(199.16,602.768))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('dx',(209.828,577.8))
+G_()
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m11',(199.16,719.968))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m12',(264.16,719.968))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m13',(329.16,719.968))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m21',(199.16,654.968))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m22',(264.16,654.968))
+fp((0,0,0))
+le()
+lw(1)
+Fn('Helvetica')
+Fs(24)
+txt('m23',(329.16,654.968))
+guidelayer('Guide Lines',1,0,0,1,(0,0,1))
+grid((0,0,5,5),1,(0,0,1),'Grid')
diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc
index c1f9ef5..b750aa0 100644
--- a/doc/src/examples.qdoc
+++ b/doc/src/examples.qdoc
@@ -234,6 +234,7 @@
\o \l{painting/fontsampler}{Font Sampler}
\o \l{painting/imagecomposition}{Image Composition}\raisedaster
\o \l{painting/painterpaths}{Painter Paths}\raisedaster
+ \o \l{painting/svggenerator}{SVG Generator}\raisedaster
\o \l{painting/svgviewer}{SVG Viewer}
\o \l{painting/transformations}{Transformations}\raisedaster
\endlist
@@ -315,6 +316,7 @@
\section1 Threads
\list
+ \o \l{threads/queuedcustomtype}{Queued Custom Type}\raisedaster
\o \l{threads/mandelbrot}{Mandelbrot}\raisedaster
\o \l{threads/semaphores}{Semaphores}\raisedaster
\o \l{threads/waitconditions}{Wait Conditions}\raisedaster
@@ -326,6 +328,8 @@
\o \l{tools/codecs}{Codecs}
\o \l{tools/completer}{Completer}\raisedaster
\o \l{tools/customcompleter}{Custom Completer}\raisedaster
+ \o \l{tools/customtype}{Custom Type}\raisedaster
+ \o \l{tools/customtypesending}{Custom Type Sending}\raisedaster
\o \l{tools/echoplugin}{Echo Plugin}\raisedaster
\o \l{tools/i18n}{I18N}
\o \l{tools/plugandpaint}{Plug & Paint}\raisedaster
diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc
index 7ea2ca2..657a204 100644
--- a/doc/src/examples/collidingmice-example.qdoc
+++ b/doc/src/examples/collidingmice-example.qdoc
@@ -66,7 +66,7 @@
\section1 Mouse Class Definition
- The \c mouse class inherits both QObject and QGraphicsItem. The
+ The \c mouse class inherits from QGraphicsItem. The
QGraphicsItem class is the base class for all graphical items in
the Graphics View framework, and provides a light-weight
foundation for writing your own custom items.
@@ -78,14 +78,11 @@
{QGraphicsItem::}{boundingRect()}, which returns an estimate of
the area painted by the item, and \l {QGraphicsItem::}{paint()},
which implements the actual painting. In addition, we reimplement
- the \l {QGraphicsItem::}{shape()} function to return an accurate
+ the \l {QGraphicsItem::}{shape()} and \l {QGraphicsItem::}{advance()}.
+ We reimplement \l {QGraphicsItem::}{shape()} to return an accurate
shape of our mouse item; the default implementation simply returns
- the item's bounding rectangle.
-
- The rationale for deriving from QObject in addition to
- QGraphicsItem is to be able to animate our items by reimplementing
- QObject's \l {QObject::}{timerEvent()} function and use
- QObject::startTimer() to generate timer events.
+ the item's bounding rectangle. We reimplement \l {QGraphicsItem::}{advance()}
+ to handle the animation so it all happens on one update.
\section1 Mouse Class Definition
@@ -105,19 +102,18 @@
calling the item's \l {QGraphicsItem::rotate()}{rotate()} function
we alter the direction in which the mouse will start moving.
- In the end we call QObject's \l {QObject::}{startTimer()}
- function, emitting a timer event every 1000/33 millisecond. This
- enables us to animate our mouse item using our reimplementation of
- the \l {QObject::}{timerEvent()} function; whenever a mouse
- receives a timer event it will trigger \l
- {QObject::}{timerEvent()}:
-
+ When the QGraphicsScene decides to advance the scene a frame it will call
+ QGraphicsItem::advance() on each of the items. This enables us to animate
+ our mouse using our reimplementation of the advance() function.
+
\snippet examples/graphicsview/collidingmice/mouse.cpp 4
\snippet examples/graphicsview/collidingmice/mouse.cpp 5
\snippet examples/graphicsview/collidingmice/mouse.cpp 6
- First we ensure that the mice stays within a circle with a radius
- of 150 pixels.
+ First, we don't bother doing any advance if the step is 0 since we want to our advance in
+ the actual advance (advance() is called twice, once with step == 0 indicating that items
+ are about to advance and with step == 1 for the actual advance). We also ensure that the
+ mice stays within a circle with a radius of 150 pixels.
Note the \l {QGraphicsItem::mapFromScene()}{mapFromScene()}
function provided by QGraphicsItem. This function maps a position
@@ -275,5 +271,12 @@
In the end, we set the application window's title and size before
we enter the main event loop using the QApplication::exec()
function.
-*/
+ Finally, we create a QTimer and connect its timeout() signal to the advance()
+ slot of the scene. Every time the timer fires, the scene will advance one frame.
+ We then tell the timer to fire every 1000/33 millisecond. This will
+ give us a frame rate of 30 frames a second, which is fast enough for most animations.
+ Doing the animation with a single timer connect to advance the scene ensures that all the
+ mice are moved at one point and, more importantly, only one update is sent to the screen
+ after all the mice have moved.
+*/ \ No newline at end of file
diff --git a/doc/src/examples/customtype.qdoc b/doc/src/examples/customtype.qdoc
new file mode 100644
index 0000000..ffeccc3
--- /dev/null
+++ b/doc/src/examples/customtype.qdoc
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example tools/customtype
+ \title Custom Type Example
+
+ The Custom Type example shows how to integrate a custom type into Qt's
+ meta-object system.
+
+ Contents:
+
+ \tableofcontents
+
+ \section1 Overview
+
+ Qt provides a range of standard value types that are used to provide
+ rich and meaningful APIs. These types are integrated with the meta-object
+ system, enabling them to be stored in QVariant objects, written out in
+ debugging information and sent between components in signal-slot
+ communication.
+
+ Custom types can also be integrated with the meta-object system as long as
+ they are written to conform to some simple guidelines. In this example, we
+ introduce a simple \c Message class, we describe how we make it work with
+ QVariant, and we show how it can be extended to generate a printable
+ representation of itself for use in debugging output.
+
+ \section1 The Message Class Definition
+
+ The \c Message class is a simple value class that contains two pieces
+ of information (a QString and a QStringList), each of which can be read
+ using trivial getter functions:
+
+ \snippet examples/tools/customtype/message.h custom type definition
+
+ The default constructor, copy constructor and destructor are
+ all required, and must be public, if the type is to be integrated into the
+ meta-object system. Other than this, we are free to implement whatever we
+ need to make the type do what we want, so we also include a constructor
+ that lets us set the type's data members.
+
+ To enable the type to be used with QVariant, we declare it using the
+ Q_DECLARE_METATYPE() macro:
+
+ \snippet examples/tools/customtype/message.h custom type meta-type declaration
+
+ We do not need to write any additional code to accompany this macro.
+
+ To allow us to see a readable description of each \c Message object when it
+ is sent to the debug output stream, we define a streaming operator:
+
+ \snippet examples/tools/customtype/message.h custom type streaming operator
+
+ This facility is useful if you need to insert tracing statements in your
+ code for debugging purposes.
+
+ \section1 The Message Class Implementation
+
+ The implementation of the default constructor, copy constructor and destructor
+ are straightforward for the \c Message class:
+
+ \snippet examples/tools/customtype/message.cpp Message class implementation
+
+ The streaming operator is implemented in the following way:
+
+ \snippet examples/tools/customtype/message.cpp custom type streaming operator
+
+ Here, we want to represent each value depending on how many lines are stored
+ in the message body. We stream text to the QDebug object passed to the
+ operator and return the QDebug object obtained from its maybeSpace() member
+ function; this is described in more detail in the
+ \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
+ document.
+
+ We include the code for the getter functions for completeness:
+
+ \snippet examples/tools/customtype/message.cpp getter functions
+
+ With the type fully defined, implemented, and integrated with the
+ meta-object system, we can now use it.
+
+ \section1 Using the Message
+
+ In the example's \c{main()} function, we show how a \c Message object can
+ be printed to the console by sending it to the debug stream:
+
+ \snippet examples/tools/customtype/main.cpp printing a custom type
+
+ You can use the type with QVariant in exactly the same way as you would
+ use standard Qt value types. Here's how to store a value using the
+ QVariant::setValue() function:
+
+ \snippet examples/tools/customtype/main.cpp storing a custom value
+
+ Alternatively, the qVariantFromValue() and qVariantSetValue() functions
+ can be used if you are using a compiler without support for member template
+ functions.
+
+ The value can be retrieved using the QVariant::value() member template
+ function:
+
+ \snippet examples/tools/customtype/main.cpp retrieving a custom value
+
+ Alternatively, the qVariantValue() template function can be used if
+ you are using a compiler without support for member template functions.
+
+ \section1 Further Reading
+
+ The custom \c Message type can also be used with direct signal-slot
+ connections; see the \l{Custom Type Sending Example} for a demonstration
+ of this.
+ To register a custom type for use with queued signals and slots, such as
+ those used in cross-thread communication, see the
+ \l{Queued Custom Type Example}.
+
+ More information on using custom types with Qt can be found in the
+ \l{Creating Custom Qt Types} document.
+*/
diff --git a/doc/src/examples/customtypesending.qdoc b/doc/src/examples/customtypesending.qdoc
new file mode 100644
index 0000000..d335c28
--- /dev/null
+++ b/doc/src/examples/customtypesending.qdoc
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example tools/customtypesending
+ \title Custom Type Sending Example
+
+ The Custom Type Sending example shows how to use a custom type with signals
+ and slots.
+
+ \image customtypesending-example.png
+
+ Contents:
+
+ \tableofcontents
+
+ \section1 Overview
+
+ In the \l{Custom Type Example}, we showed how to integrate custom types
+ with the meta-object system, enabling them to be stored in QVariant
+ objects, written out in debugging information and used in signal-slot
+ communication.
+
+ In this example, we demonstrate that the preparations made to the
+ \c Message class and its declaration with Q_DECLARE_METATYPE() enable it
+ to be used with direct signal-slot connections. We do this by creating
+ a \c Window class containing signals and slots whose signatures include
+ \c Message arguments.
+
+ \section1 The Window Class Definition
+
+ We define a simple \c Window class with a signal and public slot that
+ allow a \c Message object to be sent via a signal-slot connection:
+
+ \snippet examples/tools/customtypesending/window.h Window class definition
+
+ The window will contain a text editor to show the contents of a message
+ and a push button that the user can click to send a message. To facilitate
+ this, we also define the \c sendMessage() slot. We also keep a \c Message
+ instance in the \c thisMessage private variable which holds the actual
+ message to be sent.
+
+ \section1 The Window Class Implementation
+
+ The \c Window constructor sets up a user interface containing a text
+ editor and a push button.
+
+ \snippet examples/tools/customtypesending/window.cpp Window constructor
+
+ The button's \l{QPushButton::}{clicked()} signal is connected to the
+ window's \c{sendMessage()} slot, which emits the \c{messageSent(Message)}
+ signal with the \c Message held by the \c thisMessage variable:
+
+ \snippet examples/tools/customtypesending/window.cpp sending a message
+
+ We implement a slot to allow the message to be received, and this also
+ lets us set the message in the window programatically:
+
+ \snippet examples/tools/customtypesending/window.cpp receiving a message
+
+ In this function, we simply assign the new message to \c thisMessage
+ and update the text in the editor.
+
+ \section1 Making the Connection
+
+ In the example's \c{main()} function, we perform the connection between
+ two instances of the \c Window class:
+
+ \snippet examples/tools/customtypesending/main.cpp main function
+
+ We set the message for the first window and connect the
+ \c{messageSent(Message)} signal from each window to the other's
+ \c{setMessage(Message)} slot. Since the signals and slots mechanism is only
+ concerned with the type, we can simplify the signatures of both the
+ signal and slot when we make the connection.
+
+ When the user clicks on the \gui{Send message} button in either window,
+ the message shown will be emitted in a signal that the other window will
+ receive and display.
+
+ \section1 Further Reading
+
+ Although the custom \c Message type can be used with direct signals and
+ slots, an additional registration step needs to be performed if you want
+ to use it with queued signal-slot connections. See the
+ \l{Queued Custom Type Example} for details.
+
+ More information on using custom types with Qt can be found in the
+ \l{Creating Custom Qt Types} document.
+*/
diff --git a/doc/src/examples/extension.qdoc b/doc/src/examples/extension.qdoc
index 8a0ca3a..02e0698 100644
--- a/doc/src/examples/extension.qdoc
+++ b/doc/src/examples/extension.qdoc
@@ -80,9 +80,9 @@
user type a word to search for, we need several \l
{QCheckBox}{QCheckBox}es to facilitate the search options, and we
need three \l {QPushButton}{QPushButton}s: the \gui Find button to
- start a search, the \gui More button to enable an advanced search,
- and the \gui Close button to exit the application. Finally, we
- need a QWidget representing the application's extension part.
+ start a search and the \gui More button to enable an advanced search.
+ Finally, we need a QWidget representing the application's extension
+ part.
\section1 FindDialog Class Implementation
@@ -128,8 +128,7 @@
the connection makes sure that the extension widget is shown
depending on the state of \gui More button.
- We also connect the \gui Close button to the QWidget::close()
- slot, and we put the checkboxes associated with the advanced
+ We also put the check boxes associated with the advanced
search options into a layout we install on the extension widget.
\snippet examples/dialogs/extension/finddialog.cpp 4
@@ -137,7 +136,7 @@
Before we create the main layout, we create several child layouts
for the widgets: First we allign the QLabel ans its buddy, the
QLineEdit, using a QHBoxLayout. Then we vertically allign the
- QLabel and QLineEdit with the checkboxes associated with the
+ QLabel and QLineEdit with the check boxes associated with the
simple search, using a QVBoxLayout. We also create a QVBoxLayout
for the buttons. In the end we lay out the two latter layouts and
the extension widget using a QGridLayout.
diff --git a/doc/src/examples/queuedcustomtype.qdoc b/doc/src/examples/queuedcustomtype.qdoc
new file mode 100644
index 0000000..bbd1427
--- /dev/null
+++ b/doc/src/examples/queuedcustomtype.qdoc
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example threads/queuedcustomtype
+ \title Queued Custom Type Example
+
+ The Queued Custom Type example shows how to send custom types between
+ threads with queued signals and slots.
+
+ \image queuedcustomtype-example.png
+
+ Contents:
+
+ \tableofcontents
+
+ \section1 Overview
+
+ In the \l{Custom Type Sending Example}, we showed how to use a custom type
+ with signal-slot communication within the same thread.
+
+ In this example, we create a new value class, \c Block, and register it
+ with the meta-object system to enable us to send instances of it between
+ threads using queued signals and slots.
+
+ \section1 The Block Class
+
+ The \c Block class is similar to the \c Message class described in the
+ \l{Custom Type Example}. It provides the default constructor, copy
+ constructor and destructor in the public section of the class that the
+ meta-object system requires. It describes a colored rectangle.
+
+ \snippet examples/threads/queuedcustomtype/block.h custom type definition and meta-type declaration
+
+ We will still need to register it with the meta-object system at
+ run-time by calling the qRegisterMetaType() template function before
+ we make any signal-slot connections that use this type.
+ Even though we do not intend to use the type with QVariant in this example,
+ it is good practice to also declare the new type with Q_DECLARE_METATYPE().
+
+ The implementation of the \c Block class is trivial, so we avoid quoting
+ it here.
+
+ \section1 The Window Class
+
+ We define a simple \c Window class with a public slot that accepts a
+ \c Block object. The rest of the class is concerned with managing the
+ user interface and handling images.
+
+ \snippet examples/threads/queuedcustomtype/window.h Window class definition
+
+ The \c Window class also contains a worker thread, provided by a
+ \c RenderThread object. This will emit signals to send \c Block objects
+ to the window's \c addBlock(Block) slot.
+
+ The parts of the \c Window class that are most relevant are the constructor
+ and the \c addBlock(Block) slot.
+
+ The constructor creates a thread for rendering images, sets up a user
+ interface containing a label and two push buttons that are connected to
+ slots in the same class.
+
+ \snippet examples/threads/queuedcustomtype/window.cpp Window constructor start
+ \snippet examples/threads/queuedcustomtype/window.cpp set up widgets and connections
+ \snippet examples/threads/queuedcustomtype/window.cpp connecting signal with custom type
+
+ In the last of these connections, we connect a signal in the
+ \c RenderThread object to the \c addBlock(Block) slot in the window.
+
+ \dots
+ \snippet examples/threads/queuedcustomtype/window.cpp Window constructor finish
+
+ The rest of the constructor simply sets up the layout of the window.
+
+ The \c addBlock(Block) slot receives blocks from the rendering thread via
+ the signal-slot connection set up in the constructor:
+
+ \snippet examples/threads/queuedcustomtype/window.cpp Adding blocks to the display
+
+ We simply paint these onto the label as they arrive.
+
+ \section1 The RenderThread Class
+
+ The \c RenderThread class processes an image, creating \c Block objects
+ and using the \c sendBlock(Block) signal to send them to other components
+ in the example.
+
+ \snippet examples/threads/queuedcustomtype/renderthread.h RenderThread class definition
+
+ The constructor and destructor are not quoted here. These take care of
+ setting up the thread's internal state and cleaning up when it is destroyed.
+
+ Processing is started with the \c processImage() function, which calls the
+ \c RenderThread class's reimplementation of the QThread::run() function:
+
+ \snippet examples/threads/queuedcustomtype/renderthread.cpp processing the image (start)
+
+ Ignoring the details of the way the image is processed, we see that the
+ signal containing a block is emitted in the usual way:
+
+ \dots
+ \snippet examples/threads/queuedcustomtype/renderthread.cpp processing the image (finish)
+
+ Each signal that is emitted will be queued and delivered later to the
+ window's \c addBlock(Block) slot.
+
+ \section1 Registering the Type
+
+ In the example's \c{main()} function, we perform the registration of the
+ \c Block class as a custom type with the meta-object system by calling the
+ qRegisterMetaType() template function:
+
+ \snippet examples/threads/queuedcustomtype/main.cpp main function
+
+ This call is placed here to ensure that the type is registered before any
+ signal-slot connections are made that use it.
+
+ The rest of the \c{main()} function is concerned with setting a seed for
+ the pseudo-random number generator, creating and showing the window, and
+ setting a default image. See the source code for the implementation of the
+ \c createImage() function.
+
+ \section1 Further Reading
+
+ This example showed how a custom type can be registered with the
+ meta-object system so that it can be used with signal-slot connections
+ between threads. For ordinary communication involving direct signals and
+ slots, it is enough to simply declare the type in the way described in the
+ \l{Custom Type Sending Example}.
+
+ In practice, both the Q_DECLARE_METATYPE() macro and the qRegisterMetaType()
+ template function can be used to register custom types, but
+ qRegisterMetaType() is only required if you need to perform signal-slot
+ communication or need to create and destroy objects of the custom type
+ at run-time.
+
+ More information on using custom types with Qt can be found in the
+ \l{Creating Custom Qt Types} document.
+*/
diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc
index 7059043..fb3a1c1 100644
--- a/doc/src/examples/qxmlstreambookmarks.qdoc
+++ b/doc/src/examples/qxmlstreambookmarks.qdoc
@@ -103,8 +103,9 @@
The \c read() function accepts a QIODevice and sets it using
\l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process
- of reading only takes place in event the file is a valid XBEL 1.0
- file. Otherwise, the \l{QXmlStreamReader::raiseError()}
+ of reading only takes place if the file is a valid XBEL 1.0 file.
+ Note that the XML input needs to be well-formed to be accepted by
+ QXmlStreamReader. Otherwise, the \l{QXmlStreamReader::raiseError()}
{raiseError()} function is used to display an error message.
\snippet examples/xml/streambookmarks/xbelreader.cpp 1
diff --git a/doc/src/examples/svggenerator.qdoc b/doc/src/examples/svggenerator.qdoc
new file mode 100644
index 0000000..32bb89a
--- /dev/null
+++ b/doc/src/examples/svggenerator.qdoc
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example painting/svggenerator
+ \title SVG Generator Example
+
+ The SVG Generator example shows how to add SVG file export to applications.
+
+ \image svggenerator-example.png
+
+ Scalable Vector Graphics (SVG) is an XML-based language for describing
+ two-dimensional vector graphics. Qt provides classes for rendering and
+ generating SVG drawings. This example allows the user to create a simple
+ picture and save it to an SVG file.
+
+ The example consists of two classes: \c Window and \c DisplayWidget.
+
+ The \c Window class contains the application logic and constructs the user
+ interface from a Qt Designer \c{.ui} file as described in the
+ \l{Using a Designer .ui File in Your Application#The Multiple Inheritance Approach}{Qt Designer manual}.
+ It also contains the code to write an SVG file.
+
+ The \c DisplayWidget class performs all the work of painting a picture on
+ screen. Since we want the SVG to resemble this picture as closely as
+ possible, we make this code available to the \c Window class so that it can
+ be used to generate SVG files.
+
+ \section1 The DisplayWidget Class
+
+ The \c DisplayWidget class displays a drawing consisting of a selection of
+ elements chosen by the user. These are defined using \c Shape and
+ \c Background enums that are included within the class definition:
+
+ \snippet examples/painting/svggenerator/displaywidget.h DisplayWidget class definition
+
+ Much of this class is used to configure the appearance of the drawing. The
+ \c paintEvent() and \c paint() functions are most relevant to the purpose
+ of this example, so we will describe these here and leave the reader to
+ look at the source code for the example to see how shapes and colors are
+ handled.
+
+ We reimplement the QWidget::paintEvent() function to display the drawing
+ on screen:
+
+ \snippet examples/painting/svggenerator/displaywidget.cpp paint event
+
+ Here, we only construct a QPainter object, begin painting on the device
+ and set a render hint for improved output quality before calling the
+ \c paint() function to perform the painting itself. When this returns,
+ we close the painter and return.
+
+ The \c paint() function is designed to be used for different painting
+ tasks. In this example, we use it to draw on a \c DisplayWidget instance
+ and on a QSvgGenerator object. We show how the painting is performed to
+ demonstrate that there is nothing device-specific about the process:
+
+ \snippet examples/painting/svggenerator/displaywidget.cpp paint function
+
+ \section1 The Window Class
+
+ The \c Window class represents the example's window, containing the user
+ interface, which has been created using Qt Designer:
+
+ \snippet examples/painting/svggenerator/window.h Window class definition
+
+ As with the \c DisplayWidget class, we concentrate on the parts of the code
+ which are concerned with painting and SVG generation. In the \c Window
+ class, the \c saveSvg() function is called whenever the \gui{Save As...}
+ button is clicked; this connection was defined in the \c{window.ui} file
+ using Qt Designer.
+
+ The start of the \c saveSvg() function performs the task of showing a file
+ dialog so that the user can specify a SVG file to save the drawing to.
+
+ \snippet examples/painting/svggenerator/window.cpp save SVG
+
+ In the rest of the function, we set up the generator and configure it to
+ generate output with the appropriate dimensions and write to the
+ user-specified file. We paint on the QSvgGenerator object in the same way
+ that we paint on a widget, calling the \c DisplayWidget::paint() function
+ so that we use exactly the same code that we used to display the drawing.
+
+ The generation process itself begins with the call to the painter's
+ \l{QPainter::}{begin()} function and ends with call to its
+ \l{QPainter::}{end()} function. The QSvgGenerator paint device relies on
+ the explicit use of these functions to ensure that output is written to
+ the file.
+
+ \section1 Further Reading
+
+ The \l{SVG Viewer Example} shows how to display SVG drawings in an
+ application, and can be used to show the contents of SVG files created
+ by this example.
+
+ See the QtSvg module documentation for more information about SVG and Qt's
+ SVG classes.
+*/
diff --git a/doc/src/exportedfunctions.qdoc b/doc/src/exportedfunctions.qdoc
index 2d4821f..f67950c 100644
--- a/doc/src/exportedfunctions.qdoc
+++ b/doc/src/exportedfunctions.qdoc
@@ -101,8 +101,10 @@
press-and-hold operation on the application's dock icon or
\key{Ctrl}-clicks on it while the application is running.
- The menu will be turned into a Mac menu which will be merged
- with Mac OS X built-in commands.
+ The menu will be turned into a Mac menu and the items added to the default
+ Dock menu. There is no merging of the Qt menu items with the items that are
+ in the Dock menu (i.e., it is not recommended to include actions that
+ duplicate functionality of items already in the Dock menu).
\section1 void qt_mac_set_menubar_icons(bool \e{enable})
diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc
index 8904ddb..3bfb5af 100644
--- a/doc/src/external-resources.qdoc
+++ b/doc/src/external-resources.qdoc
@@ -352,3 +352,8 @@
\externalpage http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
\title GNU Lesser General Public License, version 2.1
*/
+
+/*!
+ \externalpage http://developers.sun.com/sunstudio/downloads/patches/index.jsp
+ \title Sun Studio Patches
+*/
diff --git a/doc/src/graphicsview.qdoc b/doc/src/graphicsview.qdoc
index fc21c53..049b0c3 100644
--- a/doc/src/graphicsview.qdoc
+++ b/doc/src/graphicsview.qdoc
@@ -77,8 +77,8 @@
\section1 The Graphics View Architecture
Graphics View provides an item-based approach to model-view programming,
- much like InterView's convenience classes QTableWidget, QTreeWidget and
- QListWidget. Several views can observe a single scene, and the scene
+ much like InterView's convenience classes QTableView, QTreeView and
+ QListView. Several views can observe a single scene, and the scene
contains items of varying geometric shapes.
\section2 The Scene
diff --git a/doc/src/images/customtypesending-example.png b/doc/src/images/customtypesending-example.png
new file mode 100644
index 0000000..fbc3953
--- /dev/null
+++ b/doc/src/images/customtypesending-example.png
Binary files differ
diff --git a/doc/src/images/extension-example.png b/doc/src/images/extension-example.png
index dfaacc0..18fab52 100644
--- a/doc/src/images/extension-example.png
+++ b/doc/src/images/extension-example.png
Binary files differ
diff --git a/doc/src/images/extension_more.png b/doc/src/images/extension_more.png
index 2b06809..407af27 100644
--- a/doc/src/images/extension_more.png
+++ b/doc/src/images/extension_more.png
Binary files differ
diff --git a/doc/src/images/qtransform-representation.png b/doc/src/images/qtransform-representation.png
index 2608872..883d5dc 100644
--- a/doc/src/images/qtransform-representation.png
+++ b/doc/src/images/qtransform-representation.png
Binary files differ
diff --git a/doc/src/images/queuedcustomtype-example.png b/doc/src/images/queuedcustomtype-example.png
new file mode 100644
index 0000000..4399b63
--- /dev/null
+++ b/doc/src/images/queuedcustomtype-example.png
Binary files differ
diff --git a/doc/src/images/svggenerator-example.png b/doc/src/images/svggenerator-example.png
new file mode 100644
index 0000000..e7a8e53
--- /dev/null
+++ b/doc/src/images/svggenerator-example.png
Binary files differ
diff --git a/doc/src/installation.qdoc b/doc/src/installation.qdoc
index 6d02801..925a195 100644
--- a/doc/src/installation.qdoc
+++ b/doc/src/installation.qdoc
@@ -614,7 +614,7 @@ in the \l{Qt for Windows CE Requirements} document.
<td><tt>-xinerama</tt> or auto-detected</td><td>1.1.0</td>
</tr><tr id="DefaultColor">
<td> Xi </td><td> libXi </td><td> X11 Input Extensions</td>
- <td>auto-detected</td><td>1.3.0</td>
+ <td><tt>-xinput</tt> or auto-detected</td><td>1.3.0</td>
</tr><tr id="DefaultColor">
<td> Xt </td><td> libXt </td><td> Xt Intrinsics</td><td></td><td>0.99</td>
</tr><tr id="DefaultColor">
diff --git a/doc/src/model-view-programming.qdoc b/doc/src/model-view-programming.qdoc
index 50d6498..bf0c1c8 100644
--- a/doc/src/model-view-programming.qdoc
+++ b/doc/src/model-view-programming.qdoc
@@ -227,9 +227,14 @@
\section2 Delegates
QAbstractItemDelegate is the abstract base class for delegates in the
- model/view framework. A default delegate implementation is provided by
- the QItemDelegate class, and this is used as the default delegate by
- Qt's standard views.
+ model/view framework. Since Qt 4.4, the default delegate implementation is
+ provided by QStyledItemDelegate, and this is used as the default delegate
+ by Qt's standard views. However, QStyledItemDelegate and QItemDelegate are
+ independent alternatives to painting and providing editors for items in
+ views. The difference between them is that QStyledItemDelegate uses the
+ current style to paint its items. We therefore recommend using
+ QStyledItemDelegate as the base class when implementing custom delegates or
+ when working with Qt style sheets.
Delegates are described in the section on \l{Delegate Classes}.
diff --git a/doc/src/phonon-api.qdoc b/doc/src/phonon-api.qdoc
index 01f7c8a..3d04c68 100644
--- a/doc/src/phonon-api.qdoc
+++ b/doc/src/phonon-api.qdoc
@@ -2568,7 +2568,7 @@
details.
Phonon also provides EffectWidget, which lets the user modify the
- parameters of an effect an the fly, e.g., with comboboxes.
+ parameters of an effect an the fly; e.g., with combo boxes.
\sa {Phonon Module}, EffectWidget
*/
@@ -2656,7 +2656,7 @@
To find out what \l{Phonon::}{AudioOutputDevice}s are available
for AudioOutput, you can call
- BackendCapabilities::availableAudioDevices(). A default device is
+ BackendCapabilities::availableAudioOutputDevices(). A default device is
selected by the backend, but it is possible to set the device to
be used with setOutputDevice(). The outputDeviceChanged() signal
will be emitted if the device changes.
diff --git a/doc/src/phonon.qdoc b/doc/src/phonon.qdoc
index e86ccf6..9470e61 100644
--- a/doc/src/phonon.qdoc
+++ b/doc/src/phonon.qdoc
@@ -49,7 +49,7 @@
\section1 Introduction
Qt uses the Phonon multimedia framework to provide functionality
- for playback of the most common multimedia formats.The media can
+ for playback of the most common multimedia formats. The media can
be read from files or streamed over a network, using a QURL to a
file.
@@ -566,7 +566,8 @@
framework, but rather use exchangeable backends to do the work.
See the \l{Phonon Module} page for general information about the
- framework.
+ framework and the \l{Phonon Overview} for an introductory tour of its
+ features.
*/
/*!
diff --git a/doc/src/platform-notes.qdoc b/doc/src/platform-notes.qdoc
index ad13c1c..c8046c4 100644
--- a/doc/src/platform-notes.qdoc
+++ b/doc/src/platform-notes.qdoc
@@ -232,9 +232,7 @@
\section1 Windows Vista
- Known issues for Qt on Vista will be listed here.
-
- As of Qt 4.2.0 no Vista-specific issues are known.
+ At the time Qt %VERSION% was released, there were no known Vista-specific issues.
\target Windows NT
\section1 Windows XP, Windows 2000 and Windows NT
@@ -404,7 +402,7 @@
Any platform-compiler combinations not listed here should be considered unsupported.
- \section2 Actively Supported Platforms
+ \section1 Actively Supported Platforms
\table
\header \o OS \o Architecture \o Makespec \o Compiler version(s)
@@ -435,7 +433,7 @@
\o wince*-msvc2008 \o Visual Studio 2008
\endtable
- \section2 Community Supported Platforms
+ \section1 Community Supported Platforms
\table
\header \o OS \o Architecture \o Makespec \o Compiler version(s)
@@ -460,7 +458,7 @@
\row \o Embedded Linux \o MIPS, PowerPC \o qws/linux-g++ \o GCC 3.4, 4.1, 4.2, 4.3
\endtable
- \section2 Unsupported Platforms
+ \section1 Unsupported Platforms
The following platforms were supported in previous releases, either as actively supported
or community supported platforms, but are now unsupported.
@@ -493,7 +491,6 @@
\row
\row \o aCC series 3 \o \o \o \o \bold{X} \o \bold{X}
\row \o aCC series 6 \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X}
- \row \o MIPSpro 7.4.2m \o{5,1} \e{Unsupported - see the Unsupported Platforms table}
\row \o xlC 6 \o \o \o \o \bold{X} \o \bold{X}
\row \o \l{Known Issues in %VERSION%}{Intel CC 10 (see note)}
\o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X}
@@ -666,9 +663,9 @@
\section2 Sun Studio
- Qt is tested using Sun Studio 10 (Sun CC 5.5). Go to
- \l{http://developers.sun.com/prodtech/cc/downloads/patches/index.html}{Sun's website}
- to download the latest patches for your Sun compiler.
+ Qt is tested using Sun Studio 8 (Sun CC 5.5). Go to
+ \l{Sun Studio Patches} page on Sun's Web site to download
+ the latest patches for your Sun compiler.
\section2 Sun WorkShop 5.0
diff --git a/doc/src/porting4-removedvirtual.qdocinc b/doc/src/porting4-removedvirtual.qdocinc
index 3eedad2..1af4fa6 100644
--- a/doc/src/porting4-removedvirtual.qdocinc
+++ b/doc/src/porting4-removedvirtual.qdocinc
@@ -22,7 +22,7 @@
\row \o void QButton::drawButtonLabel(QPainter *) \o Use Q3Button instead or reimplement QButton::paintEvent().
\row \o void QButton::setAccel(const QKeySequence &) \o Setter.
\row \o void QButton::setAutoRepeat(bool) \o Setter.
-\row \o void QButton::setDown(bool) \o Setter.
+\row \o void QButton::setDown(bool) \o Use Q3Button instead or reimplement or port to the new QPushButton API.
\row \o void QButton::setPixmap(const QPixmap &) \o Setter.
\row \o void QButton::setState(ToggleState) \o Setter.
\row \o void QButton::setText(const QString &) \o Use the QAbstractButton::setText() setter function.
diff --git a/doc/src/qalgorithms.qdoc b/doc/src/qalgorithms.qdoc
index 459fb81..b33c250 100644
--- a/doc/src/qalgorithms.qdoc
+++ b/doc/src/qalgorithms.qdoc
@@ -490,7 +490,10 @@ of \a value in the variable passed as a reference in argument \a n.
\overload
- This is the same as qLowerBound(\a{container}.begin(), \a{container}.end(), value);
+ For read-only iteration over containers, this function is broadly equivalent to
+ qLowerBound(\a{container}.begin(), \a{container}.end(), value). However, since it
+ returns a const iterator, you cannot use it to modify the container; for example,
+ to insert items.
*/
/*! \fn RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
diff --git a/doc/src/qaxcontainer.qdoc b/doc/src/qaxcontainer.qdoc
index 2138aaf..48c76fc 100644
--- a/doc/src/qaxcontainer.qdoc
+++ b/doc/src/qaxcontainer.qdoc
@@ -73,9 +73,6 @@
standard ActiveX controls to provide high-level user interface
functionality are provided.
- The QAxContainer module is part of the \l{Qt Full Framework Edition} for
- Windows. It is \e not part of the \l{Open Source Versions of Qt}.
-
\sa {ActiveQt Framework}
Topics:
diff --git a/doc/src/qaxserver.qdoc b/doc/src/qaxserver.qdoc
index ff04962..f0c317b 100644
--- a/doc/src/qaxserver.qdoc
+++ b/doc/src/qaxserver.qdoc
@@ -63,9 +63,6 @@
Some \l{Qt Examples#ActiveQt}{example implementations} of ActiveX
controls and COM objects are provided.
- The QAxServer module is part of the \l{Qt Full Framework Edition} for
- Windows. It is \e not part of the \l{Open Source Versions of Qt}.
-
\sa {ActiveQt Framework}
Topics:
diff --git a/doc/src/qdesktopwidget.qdoc b/doc/src/qdesktopwidget.qdoc
index 0361aae..5a27fb4 100644
--- a/doc/src/qdesktopwidget.qdoc
+++ b/doc/src/qdesktopwidget.qdoc
@@ -48,6 +48,9 @@
\ingroup environment
\mainclass
+ QApplication::desktop() function should be used to get an instance
+ of the QDesktopWidget.
+
Systems with more than one graphics card and monitor can manage the
physical screen space available either as multiple desktops, or as a
large virtual desktop, which usually has the size of the bounding
@@ -86,12 +89,14 @@
screens. The correct width and height values are obtained using
availableGeometry() or screenGeometry() for a particular screen.
- \sa QApplication, QX11Info::appRootWindow()
+ \sa QApplication, QApplication::desktop(), QX11Info::appRootWindow()
*/
/*!
\fn QDesktopWidget::QDesktopWidget()
+ \internal
+
Creates the desktop widget.
If the system supports a virtual desktop, this widget will have
@@ -104,6 +109,8 @@
/*!
\fn QDesktopWidget::~QDesktopWidget()
+ \internal
+
Destroys the desktop widget and frees any allocated resources.
*/
diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc
index 30da8c6..39581a2 100644
--- a/doc/src/qmake-manual.qdoc
+++ b/doc/src/qmake-manual.qdoc
@@ -367,15 +367,20 @@
\row \o debug \o The project is to be built in debug mode.
\row \o debug_and_release \o The project is built in \e both debug and
release modes.
+ \row \o debug_and_release_target \o The project is built in \e both debug
+ and release modes. TARGET is built into \e both the debug and release directories.
\row \o build_all \o If \c debug_and_release is specified, the project is
built in both debug and release modes by default.
+ \row \o autogen_precompile_source \o Automatically generates a \c .cpp file that includes
+ the precompiled header file specified in the .pro file.
\row \o ordered \o When using the \c subdirs template, this option
specifies that the directories listed should be processed in the
order in which they are given.
\row \o warn_on \o The compiler should output as many warnings as possible.
This is ignored if \c warn_off is specified.
\row \o warn_off \o The compiler should output as few warnings as possible.
- \endtable
+ \row \o copy_dir_files \o Enables the install rule to also copy directories, not just files.
+ \endtable
The \c debug_and_release option is special in that it enables \e both debug and
release versions of a project to be built. In such a case, the Makefile that
@@ -3075,6 +3080,9 @@
called \c{.qmake.cache} in parent directories of the current directory. If
it fails to find this file, it will silently ignore this step of processing.
+ If it finds a \c{.qmake.cache} file then it will process this file first before
+ it processes the project file.
+
\target LibDepend
\section1 Library Dependencies
diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc
index 6220795..d9f001e 100644
--- a/doc/src/qnamespace.qdoc
+++ b/doc/src/qnamespace.qdoc
@@ -142,7 +142,7 @@
QAction::iconVisibleInMenu property.
Menus that are currently open or menus already created in the native
- Mac OS X menubar MAY NOT pick up a change in this attribute. Changes
+ Mac OS X menubar \e{may not} pick up a change in this attribute. Changes
in the QAction::iconVisibleInMenu property will always be picked up.
\value AA_NativeWindows Ensures that widgets have native windows.
@@ -508,11 +508,11 @@
\value DirectConnection When emitted, the signal is immediately delivered to the slot.
\value QueuedConnection When emitted, the signal is queued until the event loop is
able to deliver it to the slot.
- \value
- BlockingQueuedConnection Same as QueuedConnection, except that the current thread blocks
+ \value BlockingQueuedConnection
+ Same as QueuedConnection, except that the current thread blocks
until the slot has been delivered. This connection type should
only be used for receivers in a different thread. Note that misuse
- of this type can lead to dead locks in your application.
+ of this type can lead to deadlocks in your application.
\value AutoConnection If the signal is emitted from the thread
in which the receiving object lives, the
slot is invoked directly, as with
diff --git a/doc/src/qprintdialog.qdoc b/doc/src/qprintdialog.qdoc
index 6cac1c9..a4cd18b 100644
--- a/doc/src/qprintdialog.qdoc
+++ b/doc/src/qprintdialog.qdoc
@@ -39,26 +39,34 @@
**
****************************************************************************/
+#ifdef QT3_SUPPORT
/*!
- \fn QPrinter *QPrintDialog::printer() const
+ \fn QPrinter *QPrintDialog::printer() const
- Returns a pointer to the printer this dialog configures, or 0 if
- this dialog does not operate on any printer.
+ Returns a pointer to the printer this dialog configures, or 0 if
+ this dialog does not operate on any printer.
+
+ This function is available for Unix platforms only.
*/
/*!
- \fn void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings)
+ \fn void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings)
+
+ Sets this dialog to configure printer \a printer, or no printer if \a printer
+ is null. If \a pickupSettings is true, the dialog reads most of
+ its settings from \a printer. If \a pickupSettings is false (the
+ default) the dialog keeps its old settings.
- Sets this dialog to configure printer \a printer, or no printer if \a printer
- is null. If \a pickupSettings is true, the dialog reads most of
- its settings from \a printer. If \a pickupSettings is false (the
- default) the dialog keeps its old settings.
+ This function is available for Unix platforms only.
*/
/*!
- \fn void QPrintDialog::addButton(QPushButton *button)
+ \fn void QPrintDialog::addButton(QPushButton *button)
+
+ Adds the \a button to the layout of the print dialog. The added
+ buttons are arranged from the left to the right below the
+ last groupbox of the printdialog.
- Adds the \a button to the layout of the print dialog. The added
- buttons are arranged from the left to the right below the
- last groupbox of the printdialog.
+ This function is available for Unix platforms only.
*/
+#endif
diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc
index cd66c10..5d83ef2 100644
--- a/doc/src/qt4-intro.qdoc
+++ b/doc/src/qt4-intro.qdoc
@@ -161,9 +161,9 @@
\o Support for OLE verbs and MIME data handling in \l{ActiveQt}.
\endlist
- For more information about improvements in the current release, see
- the \l{http://www.qtsoftware.com/developer/changes/changes-4.1.4/}
- {detailed list of changes}.
+ For more information about improvements in each Qt release, see
+ the \l{http://www.qtsoftware.com/developer/changes/}
+ {detailed lists of changes}.
\section1 Significant Improvements
@@ -447,11 +447,10 @@
\l{http://www.qtsoftware.com/developer/changes/changes-4.5.0}{available online}.
A \l{Known Issues in %VERSION%}{list of known issues} for this release is also
available.
- \omit
+
Changes between this release and the previous release are provided
in the \c{changes-%VERSION%} file (also
\l{http://www.qtsoftware.com/developer/changes/changes-%VERSION%}{available online}).
- \endomit
A list of other Qt 4 features can be found on the
\bold{\l{What's New in Qt 4}} page.
diff --git a/doc/src/qtcocoa-known-issues.qdoc b/doc/src/qtcocoa-known-issues.qdoc
deleted file mode 100644
index eedbd68..0000000
--- a/doc/src/qtcocoa-known-issues.qdoc
+++ /dev/null
@@ -1,168 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the documentation 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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page qtcocoa-known-issues.html
- \title Known Issues with the Qt/Mac Cocoa Port
-
- This document explains the current list of features in the Qt/Mac Cocoa port
- that are currently not working. Most of the issues will be addressed in
- upcoming snapshots and beta releases. We hope that all the issues should be
- addressed by the time the of the final 4.5.0 release.
-
- \tableofcontents
-
- \section1 What Works
-
- Here are the things that we can say about the current state of the Qt/Mac Cocoa port.
-
- \list
- \i \e{64-bit Support}:
- The Qt libraries currently do build and link as 64-bit frameworks and it is
- possible to build and run many of the Qt examples as 64-bit.
-
- \i \e{HIViews are now NSViews}:
- Every QWidget is now backed by an NSView pointer instead of an HIViewRef.
- QWidget::winId() will return an NSView pointer that can be used in other
- Cocoa technologies (e.g., Core Animation).
-
- \i \e{Some Native Dialogs Work}:
- QFileDialog and QColorDialog have been ported to use NSOpen-/NSSavePanel and
- NSColorPanel respectively. QPrintDialog and QPageSetupDialog are not in
- this release, but are on their way. Currently, none of these dialogs show
- up as sheets pending the creation of an asynchronous API.
-
- \i \e{Painting, Printing, and Styles}:
- Since printing and painting used Quartz 2D and styling used HITheme, these
- sub-systems work without any changes.
-
- \i \e {OpenGL}:
- OpenGL is fully supported,including pixel buffers and framebuffer objects.
-
- \i \e{Clipboard}:
- Using QClipboard to copy and paste data works as expected.
-
- \i \e{Mouse, Keyboard, and Wheel events}:
- Mouse, keyboard, and wheel events are dispatched to the proper
- widget. The Qt/Mac Cocoa port respects Cocoa's idea of a "First
- Responder."
-
- \endlist
-
- \section1 Current Known Issues
-
- The following are items that don't currently work, but that we plan to have
- resolved before the final release of the Qt/Mac Cocoa port. Please do not
- file bugs on these.
-
- \list
- \i \e{Carbon Support}:
- The current source tree for the Qt/Mac Cocoa port contains source for
- building Qt/Mac with Cocoa. It contains some of the source code that is
- used for the Carbon port, but it is currently not set up to build the
- Carbon Qt/Mac libraries. Please use a normal release or snapshot if you
- want to use Carbon.
-
- \i \e{Drag and Drop Support}:
- Drag and Drop is currently not implemented and needs to be ported to Cocoa,
- but using the clipboard does work at this time.
-
- \i \e {Accessibility}:
- Accessibility support is not implemented and needs to be ported to Cocoa.
-
- \i \e {Text}:
- Most text rendering works fine for Latin-1 characters. However, rendering
- non-Latin-1 characters has not been tested.
-
- \i \e {Input Methods}:
- Input methods also need to be ported to Cocoa.
-
- \i \e {Shortcuts}:
- Shortcuts that exist outside of the menu bar may not be dispatched.
-
- \i \e {Tablet Support}:
- The tablet support has not been ported from Carbon yet. However, it should
- still be possible to use the tablet as a mouse.
-
- \i \e {Phonon}:
- Phonon uses the QuickTime backend that is only available on 32-bit. Using
- Phonon in 64-bit requires a QTKit-based backend and has not been done.
-
- \i \e {Unified Toolbar}:
- The QMainWindow::setUnifiedTitleAndToolBarOnMac() method currently does nothing.
-
- \i \e {Dialogs, Tool Windows, Sheets, and Drawers}:
- At the moment, all windows are subclasses of NSWindow. This means that
- window types like drawers and sheets do not work and tool windows do not
- get the right decorations. Modal dialogs do show up at the correct window
- level, but are not yet considered "panels." Many window flags are not
- recognized.
-
- \endlist
-
- \section1 Things We Don't Expect to Support
-
- The following items that we do not plan on spending any resources on unless
- there is monumental outcry for their inclusion.
-
- \list
- \i \e{Qt3Support}:
- At this time we have no plans for making the Qt3Support module work with
- the Qt/Mac Cocoa port in 64-bit mode. Following in footsteps of Apple, we
- would like to encourage you to consider the time of going Cocoa and 64-bit
- as a chance to jettison Qt 3 constructs and classes.
-
- \i \e{Support for versions of Mac OS X below 10.5}:
- We are using methods and classes that are only available in 10.5 and
- higher. Most of these functions don't have any equivalent on earlier
- versions. We recommend using the Carbon version for earlier versions of Mac
- OS X. We anticipate keeping the Carbon port supported at least for the
- lifetime of 4.5.
-
- \i \e{Support for -no-framework or -static}:
- Cocoa requires that we load a nib in order to properly access the global
- menu bar. This nib has to reside on disk somewhere. The most logical place
- for it to reside is inside the QtGui framework. For this reason, building
- Qt as standard "dylibs" or statically is no longer supported.
-
- \endlist
-
-*/
diff --git a/doc/src/sharedlibrary.qdoc b/doc/src/sharedlibrary.qdoc
new file mode 100644
index 0000000..3febb8f
--- /dev/null
+++ b/doc/src/sharedlibrary.qdoc
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt GUI Toolkit.
+** EDITIONS: FREE, PROFESSIONAL, ENTERPRISE
+**
+****************************************************************************/
+
+/*!
+ \group deployment
+ \page sharedlibrary.html
+ \ingroup buildsystem
+
+ \title Creating Shared Libraries
+ The following sections list certain things that should be taken into
+ account when creating shared libraries.
+
+ \section1 Using Symbols from Shared Libraries
+
+ Symbols - functions, variables or classes - contained in shared libraries
+ intended to be used by \e{clients}, such as applications or other
+ libraries, must be marked in a special way. These symbols are called
+ \e{public symbols} that are \e{exported} or made publicly visible.
+
+ The remaining symbols should not be visible from the outside. On most
+ platforms, compilers will hide them by default. On some platforms, a
+ special compiler option is required to hide these symbols.
+
+ When compiling a shared library, it must be marked for \e{export}. To use
+ the shared library from a client, some platforms may require a special
+ \e{import} declaration as well.
+
+ Depending on your target platform, Qt provides special macros that contain
+ the necessary definitions:
+ \list
+ \o \c{Q_DECL_EXPORT} must be added to the declarations of symbols used
+ when compiling a shared library.
+ \o \c{Q_DECL_IMPORT} must be added to the declarations of symbols used
+ when compiling a client that uses the shared library.
+ \endlist
+
+ Now, we need to ensure that the right macro is invoked -- whether we
+ compile a share library itself, or just the client using the shared
+ library.
+ Typically, this can be solved by adding a special header.
+
+ Let us assume we want to create a shared library called \e{mysharedlib}.
+ A special header for this library, \c{mysharedlib_global.h}, looks like
+ this:
+
+ \code
+ #include <QtCore/QtGlobal>
+
+ #if defined(MYSHAREDLIB_LIBRARY)
+ # define MYSHAREDLIB_EXPORT Q_DECL_EXPORT
+ #else
+ # define MYSHAREDLIB_EXPORT Q_DECL_IMPORT
+ #endif
+ \endcode
+
+ In the \c{.pro} file of the shared library, we add:
+
+ \code
+ DEFINES += MYSHAREDLIB_LIBRARY
+ \endcode
+
+ In each header of the library, we specify the following:
+
+ \code
+ #include "mysharedlib_global.h"
+
+ MYSHAREDLIB_EXPORT void foo();
+ class MYSHAREDLIB_EXPORT MyClass...
+ \endcode
+ This ensures that the right macro is seen by both library and clients. We
+ also use this technique in Qt's sources.
+
+
+ \section1 Header File Considerations
+
+ Typically, clients will include only the public header files of shared
+ libraries. These libraries might be installed in a different location, when
+ deployed. Therefore, it is important to exclude other internal header files
+ that were used when building the shared library.
+
+ For example, the library might provide a class that wraps a hardware device
+ and contains a handle to that device, provided by some 3rd-party library:
+
+ \code
+ #include <footronics/device.h>
+
+ class MyDevice {
+ private:
+ FOOTRONICS_DEVICE_HANDLE handle;
+ };
+ \endcode
+
+ A similar situation arises with forms created by Qt Designer when using
+ aggregation or multiple inheritance:
+
+ \code
+ #include "ui_widget.h"
+
+ class MyWidget : public QWidget {
+ private:
+ Ui::MyWidget m_ui;
+ };
+ \endcode
+
+ When deploying the library, there should be no dependency to the internal
+ headers \c{footronics/device.h} or \c{ui_widget.h}.
+
+ This can be avoided by making use of the \e{Pointer to implementation}
+ idiom described in various C++ programming books. For classes with
+ \e{value semantics}, consider using QSharedDataPointer.
+
+
+ \section1 Binary compatibility
+
+ For clients loading a shared library, to work correctly, the memory
+ layout of the classes being used must match exactly the memory layout of
+ the library version that was used to compile the client. In other words,
+ the library found by the client at runtime must be \e{binary compatible}
+ with the version used at compile time.
+
+ This is usually not a problem if the client is a self-contained software
+ package that ships all the libraries it needs.
+
+ However, if the client application relies on a shared library that belongs
+ to a different installation package or to the operating system, then we
+ need to think of a versioning scheme for shared libraries and decide at
+ which level \e{Binary compatibility} is to be maintained. For example, Qt
+ libraries of the same \e{major version number} are guaranteed to be binary
+ compatible.
+
+ Maintaining \e{Binary compatibility} places some restrictions on the changes
+ you can make to the classes. A good explanation can be found at
+ \l{http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++}
+ {KDE - Policies/Binary Compatibility Issues With C++}. These issues should
+ be considered right from the start of library design.
+ We recommend that the principle of \e{Information hiding} and the
+ \e{Pointer to implementation} technique be used wherever possible.
+*/
diff --git a/doc/src/snippets/alphachannel.cpp b/doc/src/snippets/alphachannel.cpp
index 7783271..ad0885a 100644
--- a/doc/src/snippets/alphachannel.cpp
+++ b/doc/src/snippets/alphachannel.cpp
@@ -47,11 +47,8 @@
#include <qfile.h>
#include <qdir.h>
#include <qfileinfo.h>
-
-#if (QT_VERSION) >= 0x040000
#include <QtGui>
#include <QtCore>
-#endif
class MyClass : public QWidget
{
@@ -95,12 +92,10 @@ protected:
//! [0]
}
- QPixmap channelImage, pixmap;
+ QPixmap channelImage, pixmap;
QSize sizeHint() const { return QSize(500, 500); }
};
-
-
int main(int argc, char **argv)
{
QApplication app(argc, argv);
diff --git a/doc/src/snippets/code/doc_src_deployment.qdoc b/doc/src/snippets/code/doc_src_deployment.qdoc
index 844041a..b8bf571 100644
--- a/doc/src/snippets/code/doc_src_deployment.qdoc
+++ b/doc/src/snippets/code/doc_src_deployment.qdoc
@@ -407,3 +407,8 @@ Versions/A/QuartzCore libphonon_qt7.dylib
QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.4u.sdk
CONFIG+=x86 ppc
//! [53]
+
+
+//! [54]
+qApp->addLibraryPath("C:/customPath/plugins");
+//! [54]
diff --git a/doc/src/snippets/code/doc_src_installation.qdoc b/doc/src/snippets/code/doc_src_installation.qdoc
index 66bb998..e35dad9 100644
--- a/doc/src/snippets/code/doc_src_installation.qdoc
+++ b/doc/src/snippets/code/doc_src_installation.qdoc
@@ -44,7 +44,7 @@ PATH - to locate qmake, moc and other Qt tools
//! [8]
C:
-cd /D C:\Qt\4.4.0-rc1
+cd /D C:\Qt\%VERSION%
configure
//! [8]
diff --git a/doc/src/snippets/code/doc_src_qtestlib.qdoc b/doc/src/snippets/code/doc_src_qtestlib.qdoc
index a4ef52e..ff52b2f 100644
--- a/doc/src/snippets/code/doc_src_qtestlib.qdoc
+++ b/doc/src/snippets/code/doc_src_qtestlib.qdoc
@@ -69,7 +69,7 @@ void TestQString::toUpper()
//! [10]
********* Start testing of TestQString *********
-Config: Using QTest library 4.1.0, Qt 4.1.0
+Config: Using QTest library %VERSION%, Qt %VERSION%
PASS : TestQString::initTestCase()
PASS : TestQString::toUpper()
PASS : TestQString::cleanupTestCase()
@@ -99,4 +99,4 @@ private slots:
}
}
};
-//! [12] \ No newline at end of file
+//! [12]
diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp
index 72663e9..287181a 100644
--- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp
+++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp
@@ -456,3 +456,11 @@ class MyClass : public QObject
//! [45]
QWidget w = QWidget();
//! [45]
+
+//! [46]
+ // Instead of comparing with 0.0
+ qFuzzyCompare(0.0,1.0e-200); // This will return false
+ // Compare adding 1 to both values will fix the problem
+ qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true
+//! [46]
+
diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp
index ca18465..c181a40 100644
--- a/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp
+++ b/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp
@@ -71,7 +71,7 @@ for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
//! [methodCount]
//! [6]
-int methodIndex = pushButton->metaObject()->indexForMethod("animateClick");
+int methodIndex = pushButton->metaObject()->indexOfMethod("animateClick()");
QMetaMethod method = metaObject->method(methodIndex);
method.invoke(pushButton, Qt::QueuedConnection);
//! [6]
@@ -82,7 +82,8 @@ QMetaMethod::invoke: Unable to handle unregistered datatype 'MyType'
//! [8]
QString retVal;
-int methodIndex = obj->metaObject()->indexForMethod("compute");
+QByteArray normalizedSignature = QMetaObject::normalizedSignature("compute(QString, int, double)");
+int methodIndex = obj->metaObject()->indexOfMethod(normalizedSignature);
QMetaMethod method = metaObject->method(methodIndex);
method.invoke(obj,
Qt::DirectConnection,
diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
index 355a237..783852b 100644
--- a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
+++ b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp
@@ -33,7 +33,7 @@ MyStruct s2 = var.value<MyStruct>();
//! [3]
int id = QMetaType::type("MyClass");
-if (id != -1) {
+if (id == 0) {
void *myClassPtr = QMetaType::construct(id);
...
QMetaType::destroy(id, myClassPtr);
diff --git a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp
index a9c630b..5001984 100644
--- a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp
+++ b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp
@@ -11,7 +11,10 @@ public slots:
QDesktopServices::setUrlHandler("help", helpInstance, "showHelp");
//! [0]
-
//! [1]
mailto:user@foo.com?subject=Test&body=Just a test
//! [1]
+
+//! [2]
+QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl::TolerantMode));
+//! [2]
diff --git a/doc/src/snippets/qdebug/qdebug.pro b/doc/src/snippets/qdebug/qdebug.pro
new file mode 100644
index 0000000..e62a71c
--- /dev/null
+++ b/doc/src/snippets/qdebug/qdebug.pro
@@ -0,0 +1 @@
+SOURCES = qdebugsnippet.cpp
diff --git a/doc/src/snippets/qdebugsnippet.cpp b/doc/src/snippets/qdebug/qdebugsnippet.cpp
index 4c0d80d..b713f21 100644
--- a/doc/src/snippets/qdebugsnippet.cpp
+++ b/doc/src/snippets/qdebug/qdebugsnippet.cpp
@@ -62,9 +62,13 @@ QDebug operator<<(QDebug dbg, const Coordinate &c)
int main(int argv, char **args)
{
- Coordinate nate;
- nate.myX = 10;
- nate.myY = 44;
+ Coordinate coordinate;
+ coordinate.myX = 10;
+ coordinate.myY = 44;
- qDebug() << nate;
+//! [1]
+ qDebug() << "Date:" << QDate::currentDate();
+ qDebug() << "Types:" << QString("String") << QChar('x') << QRect(0, 10, 50, 40);
+ qDebug() << "Custom coordinate type:" << coordinate;
+//! [1]
}
diff --git a/doc/src/snippets/qxmlstreamwriter/main.cpp b/doc/src/snippets/qxmlstreamwriter/main.cpp
new file mode 100644
index 0000000..a0e7010
--- /dev/null
+++ b/doc/src/snippets/qxmlstreamwriter/main.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QXmlStreamWriter>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ QFile output;
+ output.open(stdout, QIODevice::WriteOnly);
+//! [write output]
+//! [start stream]
+ QXmlStreamWriter stream(&output);
+ stream.setAutoFormatting(true);
+ stream.writeStartDocument();
+//! [start stream]
+ stream.writeDTD("<!DOCTYPE xbel>");
+ stream.writeStartElement("xbel");
+ stream.writeAttribute("version", "1.0");
+ stream.writeStartElement("folder");
+ stream.writeAttribute("folded", "no");
+//! [write element]
+ stream.writeStartElement("bookmark");
+ stream.writeAttribute("href", "http://www.qtsoftware.com/");
+ stream.writeTextElement("title", "Qt Software");
+ stream.writeEndElement(); // bookmark
+//! [write element]
+ stream.writeEndElement(); // folder
+ stream.writeEndElement(); // xbel
+//! [finish stream]
+ stream.writeEndDocument();
+//! [finish stream]
+//! [write output]
+ output.close();
+ return 0;
+}
diff --git a/doc/src/snippets/qxmlstreamwriter/qxmlstreamwriter.pro b/doc/src/snippets/qxmlstreamwriter/qxmlstreamwriter.pro
new file mode 100644
index 0000000..8f74a5d
--- /dev/null
+++ b/doc/src/snippets/qxmlstreamwriter/qxmlstreamwriter.pro
@@ -0,0 +1,2 @@
+SOURCES = main.cpp
+QT += xml
diff --git a/doc/src/snippets/xml/prettyprint/main.cpp b/doc/src/snippets/xml/prettyprint/main.cpp
index 90f9f15..fa13ff6 100644
--- a/doc/src/snippets/xml/prettyprint/main.cpp
+++ b/doc/src/snippets/xml/prettyprint/main.cpp
@@ -48,7 +48,7 @@
#include <QXmlStreamReader>
/*
- This class exists for the solve purpose of creating a translation context.
+ This class exists for the sole purpose of creating a translation context.
*/
class PrettyPrint
{
diff --git a/doc/src/trolltech-webpages.qdoc b/doc/src/trolltech-webpages.qdoc
index 5483a61..3897fcf 100644
--- a/doc/src/trolltech-webpages.qdoc
+++ b/doc/src/trolltech-webpages.qdoc
@@ -45,7 +45,7 @@
*/
/*!
- \externalpage http://www.qtsoftware.com/developer/notes/platforms/bugreport-form
+ \externalpage http://www.qtsoftware.com/bugreport-form
\title Bug Report Form
*/
diff --git a/doc/src/tutorials/addressbook-sdk.qdoc b/doc/src/tutorials/addressbook-sdk.qdoc
deleted file mode 100644
index af0013e..0000000
--- a/doc/src/tutorials/addressbook-sdk.qdoc
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the documentation 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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page tutorials-addressbook-sdk.html
-
- \startpage {index.html}{Qt Reference Documentation}
- \nextpage \l{Designing the User Interface}{Chapter 1}
-
- \title Address Book Tutorial
- \ingroup howto
- \ingroup tutorials
- \brief An introduction to GUI programming with Qt and Qt Creator,
- describing in detail how to put together a simple yet fully-
- functioning application.
-
- This tutorial gives an introduction to GUI programming using the Qt SDK.
-
- ### Screenshot
-
- In the process, we will learn about some basic technologies provided by
- Qt, such as:
-
- \list
- \o Widgets and layout managers
- \o Container classes
- \o Signals and slots
- \o Input and output devices
- \endlist
-
- If you are completely new to Qt, please read \l{How to Learn Qt} if you
- have not already done so.
-
- The tutorial's source code is located in Qt's
- \c{examples/tutorials/addressbook} directory.
-
- Tutorial chapters:
-
- \list 1
- \o \l{Designing the User Interface}
- \o \l{Adding Addresses}
- \o \l{Navigating between Entries}
- \o \l{Editing and Removing Addresses}
- \o \l{Adding a Find Function}
- \o \l{Loading and Saving}
- \o \l{Additional Features}
- \endlist
-
- Although this little application does not look much like a fully-fledged
- modern GUI application, it uses many of the basic techniques that are used
- in more complex applications. After you have worked through it, we
- recommend checking out the \l{mainwindows/application}{Application}
- example, which presents a small GUI application, with menus, toolbars, a
- status bar, and so on.
-*/
-
-
-/*!
- \page tutorials-addressbook-sdk-part1.html
- \contentspage {Address Book Tutorial}{Contents}
- \nextpage \l{Adding Addresses}{Chapter 2}
- \title Address Book 1 - Designing the User Interface
-
- The first part of this tutorial covers the design of the basic graphical
- user interface (GUI) we use for the Address Book application.
-
- The first step to creating a GUI program is to design the user interface.
- In this chapter, our goal is to set up the labels and input fields needed
- to implement a basic address book application. The figure below is a
- screenshot of our expected output.
-
- ### screenshot
-
- We begin by launching Qt Creator and use it to generate a new project. To
- do this, select \gui New from the \gui File menu. In the
- \gui{New File or Project}
-
-*/
diff --git a/doc/src/tutorials/widgets-tutorial.qdoc b/doc/src/tutorials/widgets-tutorial.qdoc
index ce977f3..ead44af 100644
--- a/doc/src/tutorials/widgets-tutorial.qdoc
+++ b/doc/src/tutorials/widgets-tutorial.qdoc
@@ -80,7 +80,7 @@
\raw HTML
<table align="left" width="100%">
- <tr><td>
+ <tr class="qt-code"><td>
\endraw
\snippet snippets/widgets-tutorial/toplevel/main.cpp create, resize and show
\raw HTML
@@ -98,7 +98,7 @@
\raw HTML
<table align="left" width="100%">
- <tr><td>
+ <tr class="qt-code"><td>
\endraw
\snippet snippets/widgets-tutorial/childwidget/main.cpp create, position and show
\raw HTML
@@ -123,7 +123,7 @@
\raw HTML
<table align="left" width="100%">
- <tr><td>
+ <tr class="qt-code"><td>
\endraw
\snippet snippets/widgets-tutorial/windowlayout/main.cpp create, lay out widgets and show
\raw HTML
@@ -157,7 +157,7 @@
\raw HTML
<table align="left" width="100%">
- <tr><td>
+ <tr class="qt-code"><td>
\endraw
\snippet snippets/widgets-tutorial/nestedlayouts/main.cpp create, lay out widgets and show
\raw HTML
@@ -171,23 +171,4 @@
As well as QHBoxLayout and QVBoxLayout, Qt also provides QGridLayout
and QFormLayout classes to help with more complex user interfaces.
-
-
-
- \omit
- In the simple example below, the widget is created on the stack and will
- automatically be deleted when the \c{main()} function exits.
-
- {{{#include <QtGui>
-
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
- QWidget window;
- window.resize(480, 360);
- window.show();
- return app.exec();
- }
- }}}
- \endomit
*/
diff --git a/examples/dialogs/standarddialogs/dialog.cpp b/examples/dialogs/standarddialogs/dialog.cpp
index 0fe1f7e..1f7c5ef 100644
--- a/examples/dialogs/standarddialogs/dialog.cpp
+++ b/examples/dialogs/standarddialogs/dialog.cpp
@@ -59,7 +59,7 @@ Dialog::Dialog(QWidget *parent)
integerLabel = new QLabel;
integerLabel->setFrameStyle(frameStyle);
QPushButton *integerButton =
- new QPushButton(tr("QInputDialog::get&Integer()"));
+ new QPushButton(tr("QInputDialog::get&Int()"));
doubleLabel = new QLabel;
doubleLabel->setFrameStyle(frameStyle);
@@ -198,8 +198,8 @@ void Dialog::setInteger()
{
//! [0]
bool ok;
- int i = QInputDialog::getInteger(this, tr("QInputDialog::getInteger()"),
- tr("Percentage:"), 25, 0, 100, 1, &ok);
+ int i = QInputDialog::getInt(this, tr("QInputDialog::getInteger()"),
+ tr("Percentage:"), 25, 0, 100, 1, &ok);
if (ok)
integerLabel->setText(tr("%1%").arg(i));
//! [0]
diff --git a/examples/graphicsview/collidingmice/main.cpp b/examples/graphicsview/collidingmice/main.cpp
index 4a44481..23c91b0 100644
--- a/examples/graphicsview/collidingmice/main.cpp
+++ b/examples/graphicsview/collidingmice/main.cpp
@@ -83,6 +83,10 @@ int main(int argc, char **argv)
view.resize(400, 300);
view.show();
+ QTimer timer;
+ QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance()));
+ timer.start(1000 / 33);
+
return app.exec();
}
//! [6]
diff --git a/examples/graphicsview/collidingmice/mouse.cpp b/examples/graphicsview/collidingmice/mouse.cpp
index 1d10574..bbdb4e3 100644
--- a/examples/graphicsview/collidingmice/mouse.cpp
+++ b/examples/graphicsview/collidingmice/mouse.cpp
@@ -65,7 +65,6 @@ Mouse::Mouse()
color(qrand() % 256, qrand() % 256, qrand() % 256)
{
rotate(qrand() % (360 * 16));
- startTimer(1000 / 33);
}
//! [0]
@@ -123,8 +122,10 @@ void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *
//! [3]
//! [4]
-void Mouse::timerEvent(QTimerEvent *)
+void Mouse::advance(int step)
{
+ if (!step)
+ return;
//! [4]
// Don't move too far away
//! [5]
diff --git a/examples/graphicsview/collidingmice/mouse.h b/examples/graphicsview/collidingmice/mouse.h
index 832ea53..c08ce4a 100644
--- a/examples/graphicsview/collidingmice/mouse.h
+++ b/examples/graphicsview/collidingmice/mouse.h
@@ -43,13 +43,10 @@
#define MOUSE_H
#include <QGraphicsItem>
-#include <QObject>
//! [0]
-class Mouse : public QObject, public QGraphicsItem
+class Mouse : public QGraphicsItem
{
- Q_OBJECT
-
public:
Mouse();
@@ -59,7 +56,7 @@ public:
QWidget *widget);
protected:
- void timerEvent(QTimerEvent *event);
+ void advance(int step);
private:
qreal angle;
diff --git a/examples/itemviews/stardelegate/stardelegate.cpp b/examples/itemviews/stardelegate/stardelegate.cpp
index 6c3677e..1e12971 100644
--- a/examples/itemviews/stardelegate/stardelegate.cpp
+++ b/examples/itemviews/stardelegate/stardelegate.cpp
@@ -58,7 +58,7 @@ void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
starRating.paint(painter, option.rect, option.palette,
StarRating::ReadOnly);
} else {
- QItemDelegate::paint(painter, option, index);
+ QStyledItemDelegate::paint(painter, option, index);
}
//! [0]
}
@@ -71,7 +71,7 @@ QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option,
StarRating starRating = qVariantValue<StarRating>(index.data());
return starRating.sizeHint();
} else {
- return QItemDelegate::sizeHint(option, index);
+ return QStyledItemDelegate::sizeHint(option, index);
}
}
//! [1]
@@ -88,7 +88,7 @@ QWidget *StarDelegate::createEditor(QWidget *parent,
this, SLOT(commitAndCloseEditor()));
return editor;
} else {
- return QItemDelegate::createEditor(parent, option, index);
+ return QStyledItemDelegate::createEditor(parent, option, index);
}
}
//! [2]
@@ -102,7 +102,7 @@ void StarDelegate::setEditorData(QWidget *editor,
StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
starEditor->setStarRating(starRating);
} else {
- QItemDelegate::setEditorData(editor, index);
+ QStyledItemDelegate::setEditorData(editor, index);
}
}
//! [3]
@@ -115,7 +115,7 @@ void StarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
model->setData(index, qVariantFromValue(starEditor->starRating()));
} else {
- QItemDelegate::setModelData(editor, model, index);
+ QStyledItemDelegate::setModelData(editor, model, index);
}
}
//! [4]
diff --git a/examples/itemviews/stardelegate/stardelegate.h b/examples/itemviews/stardelegate/stardelegate.h
index 8333da9..84814ed 100644
--- a/examples/itemviews/stardelegate/stardelegate.h
+++ b/examples/itemviews/stardelegate/stardelegate.h
@@ -42,15 +42,15 @@
#ifndef STARDELEGATE_H
#define STARDELEGATE_H
-#include <QItemDelegate>
+#include <QStyledItemDelegate>
//! [0]
-class StarDelegate : public QItemDelegate
+class StarDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
- StarDelegate(QWidget *parent = 0) : QItemDelegate(parent) {}
+ StarDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
diff --git a/examples/layouts/flowlayout/flowlayout.cpp b/examples/layouts/flowlayout/flowlayout.cpp
index d1e857d..c4032d0 100644
--- a/examples/layouts/flowlayout/flowlayout.cpp
+++ b/examples/layouts/flowlayout/flowlayout.cpp
@@ -43,16 +43,16 @@
#include "flowlayout.h"
-FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing)
- : QLayout(parent)
+FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
+ : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
- setMargin(margin);
- setSpacing(spacing);
+ setContentsMargins(margin, margin, margin, margin);
}
-FlowLayout::FlowLayout(int spacing)
+FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
+ : m_hSpace(hSpacing), m_vSpace(vSpacing)
{
- setSpacing(spacing);
+ setContentsMargins(margin, margin, margin, margin);
}
FlowLayout::~FlowLayout()
@@ -67,6 +67,24 @@ void FlowLayout::addItem(QLayoutItem *item)
itemList.append(item);
}
+int FlowLayout::horizontalSpacing() const
+{
+ if (m_hSpace >= 0) {
+ return m_hSpace;
+ } else {
+ return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
+ }
+}
+
+int FlowLayout::verticalSpacing() const
+{
+ if (m_vSpace >= 0) {
+ return m_vSpace;
+ } else {
+ return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
+ }
+}
+
int FlowLayout::count() const
{
return itemList.size();
@@ -125,20 +143,27 @@ QSize FlowLayout::minimumSize() const
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
- int x = rect.x();
- int y = rect.y();
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
+ int x = effectiveRect.x();
+ int y = effectiveRect.y();
int lineHeight = 0;
QLayoutItem *item;
foreach (item, itemList) {
QWidget *wid = item->widget();
- int spaceX = spacing() + wid->style()->layoutSpacing(
+ int spaceX = horizontalSpacing();
+ if (spaceX == -1)
+ spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
- int spaceY = spacing() + wid->style()->layoutSpacing(
+ int spaceY = verticalSpacing();
+ if (spaceY == -1)
+ spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX;
- if (nextX - spaceX > rect.right() && lineHeight > 0) {
- x = rect.x();
+ if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
+ x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
@@ -150,5 +175,19 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
- return y + lineHeight - rect.y();
+ return y + lineHeight - rect.y() + bottom;
+}
+
+int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
+{
+ QObject *parent = this->parent();
+ if (!parent) {
+ return -1;
+ } else if (parent->isWidgetType()) {
+ QWidget *pw = static_cast<QWidget *>(parent);
+ return pw->style()->pixelMetric(pm, 0, pw);
+ } else {
+ return static_cast<QLayout *>(parent)->spacing();
+ }
}
+
diff --git a/examples/layouts/flowlayout/flowlayout.h b/examples/layouts/flowlayout/flowlayout.h
index f864d8e..9940e55 100644
--- a/examples/layouts/flowlayout/flowlayout.h
+++ b/examples/layouts/flowlayout/flowlayout.h
@@ -49,11 +49,13 @@
class FlowLayout : public QLayout
{
public:
- FlowLayout(QWidget *parent, int margin = -1, int spacing = 0);
- FlowLayout(int spacing = 0);
+ FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
+ FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayout();
void addItem(QLayoutItem *item);
+ int horizontalSpacing() const;
+ int verticalSpacing() const;
Qt::Orientations expandingDirections() const;
bool hasHeightForWidth() const;
int heightForWidth(int) const;
@@ -66,8 +68,11 @@ public:
private:
int doLayout(const QRect &rect, bool testOnly) const;
+ int smartSpacing(QStyle::PixelMetric pm) const;
QList<QLayoutItem *> itemList;
+ int m_hSpace;
+ int m_vSpace;
};
#endif
diff --git a/examples/painting/painting.pro b/examples/painting/painting.pro
index b6fad5a..6d00720 100644
--- a/examples/painting/painting.pro
+++ b/examples/painting/painting.pro
@@ -7,7 +7,7 @@ SUBDIRS = basicdrawing \
!wince*: SUBDIRS += fontsampler
-contains(QT_CONFIG, svg): SUBDIRS += svgviewer
+contains(QT_CONFIG, svg): SUBDIRS += svggenerator svgviewer
# install
target.path = $$[QT_INSTALL_EXAMPLES]/painting
diff --git a/examples/painting/svggenerator/displaywidget.cpp b/examples/painting/svggenerator/displaywidget.cpp
new file mode 100644
index 0000000..c973341
--- /dev/null
+++ b/examples/painting/svggenerator/displaywidget.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include "displaywidget.h"
+
+DisplayWidget::DisplayWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QPainterPath car;
+ QPainterPath house;
+
+ QFile file(":resources/shapes.dat");
+ file.open(QFile::ReadOnly);
+ QDataStream stream(&file);
+ stream >> car >> house >> tree >> moon;
+ file.close();
+
+ shapeMap[Car] = car;
+ shapeMap[House] = house;
+
+ background = Sky;
+ shapeColor = Qt::darkYellow;
+ shape = House;
+}
+
+//! [paint event]
+void DisplayWidget::paintEvent(QPaintEvent *event)
+{
+ QPainter painter;
+ painter.begin(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ paint(painter);
+ painter.end();
+}
+//! [paint event]
+
+//! [paint function]
+void DisplayWidget::paint(QPainter &painter)
+{
+//![paint picture]
+ painter.setClipRect(QRect(0, 0, 200, 200));
+ painter.setPen(Qt::NoPen);
+
+ switch (background) {
+ case Sky:
+ default:
+ painter.fillRect(QRect(0, 0, 200, 200), Qt::darkBlue);
+ painter.translate(145, 10);
+ painter.setBrush(Qt::white);
+ painter.drawPath(moon);
+ painter.translate(-145, -10);
+ break;
+ case Trees:
+ {
+ painter.fillRect(QRect(0, 0, 200, 200), Qt::darkGreen);
+ painter.setBrush(Qt::green);
+ painter.setPen(Qt::black);
+ for (int y = -55, row = 0; y < 200; y += 50, ++row) {
+ int xs;
+ if (row == 2 || row == 3)
+ xs = 150;
+ else
+ xs = 50;
+ for (int x = 0; x < 200; x += xs) {
+ painter.save();
+ painter.translate(x, y);
+ painter.drawPath(tree);
+ painter.restore();
+ }
+ }
+ break;
+ }
+ case Road:
+ painter.fillRect(QRect(0, 0, 200, 200), Qt::gray);
+ painter.setPen(QPen(Qt::white, 4, Qt::DashLine));
+ painter.drawLine(QLine(0, 35, 200, 35));
+ painter.drawLine(QLine(0, 165, 200, 165));
+ break;
+ }
+
+ painter.setBrush(shapeColor);
+ painter.setPen(Qt::black);
+ painter.translate(100, 100);
+ painter.drawPath(shapeMap[shape]);
+//![paint picture]
+}
+//! [paint function]
+
+QColor DisplayWidget::color() const
+{
+ return shapeColor;
+}
+
+void DisplayWidget::setBackground(Background background)
+{
+ this->background = background;
+ update();
+}
+
+void DisplayWidget::setColor(const QColor &color)
+{
+ this->shapeColor = color;
+ update();
+}
+
+void DisplayWidget::setShape(Shape shape)
+{
+ this->shape = shape;
+ update();
+}
diff --git a/util/scripts/win-binary/nsis/qtnsisext/licensefinder.h b/examples/painting/svggenerator/displaywidget.h
index 0957d65..58ad97e 100644
--- a/util/scripts/win-binary/nsis/qtnsisext/licensefinder.h
+++ b/examples/painting/svggenerator/displaywidget.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,37 +38,43 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef LICENSEFINDER_H
-#define LICENSEFINDER_H
-#define MAX_KEY_LENGTH 512
-#define MAX_LICENSEE_LENGTH 512
-#define MAX_QT3INFO_LENGTH 512
+#ifndef DISPLAYWIDGET_H
+#define DISPLAYWIDGET_H
-typedef unsigned long ulong;
+#include <QColor>
+#include <QHash>
+#include <QWidget>
-class LicenseFinder
+//! [DisplayWidget class definition]
+class DisplayWidget : public QWidget
{
+ Q_OBJECT
+
public:
- LicenseFinder();
- char *getLicenseKey();
- char *getOldLicenseKey();
- char *getLicensee();
- char *getCustomerID();
- char *getProducts();
- char *getExpiryDate();
+ enum Shape { House = 0, Car = 1 };
+ enum Background { Sky = 0, Trees = 1, Road = 2 };
+
+ DisplayWidget(QWidget *parent = 0);
+ QColor color() const;
+ void paint(QPainter &painter);
+
+public slots:
+ void setBackground(Background background);
+ void setColor(const QColor &color);
+ void setShape(Shape shape);
+
+protected:
+ void paintEvent(QPaintEvent *event);
private:
- void searchLicense();
- bool lookInDirectory(const char* dir);
- char *findPattern(char *h, const char *n, ulong hlen);
- bool searched;
- char m_key[MAX_KEY_LENGTH];
- char m_oldkey[MAX_KEY_LENGTH];
- char licensee[MAX_LICENSEE_LENGTH];
- char m_customerId[MAX_QT3INFO_LENGTH];
- char m_products[MAX_QT3INFO_LENGTH];
- char m_expiryDate[MAX_QT3INFO_LENGTH];
+ Background background;
+ QColor shapeColor;
+ Shape shape;
+ QHash<Shape,QPainterPath> shapeMap;
+ QPainterPath moon;
+ QPainterPath tree;
};
+//! [DisplayWidget class definition]
-#endif \ No newline at end of file
+#endif
diff --git a/examples/painting/svggenerator/forms/window.ui b/examples/painting/svggenerator/forms/window.ui
new file mode 100644
index 0000000..bf11908
--- /dev/null
+++ b/examples/painting/svggenerator/forms/window.ui
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Window</class>
+ <widget class="QWidget" name="Window">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>339</width>
+ <height>353</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>SVG Generator</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
+ <item row="0" column="0">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="1">
+ <widget class="DisplayWidget" name="displayWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>200</horstretch>
+ <verstretch>200</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>200</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&amp;Shape:</string>
+ </property>
+ <property name="buddy">
+ <cstring>shapeComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="shapeComboBox">
+ <item>
+ <property name="text">
+ <string>House</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Car</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&amp;Color:</string>
+ </property>
+ <property name="buddy">
+ <cstring>colorButton</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QToolButton" name="colorButton">
+ <property name="text">
+ <string>Choose Color...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>&amp;Background:</string>
+ </property>
+ <property name="buddy">
+ <cstring>shapeComboBox_2</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="shapeComboBox_2">
+ <item>
+ <property name="text">
+ <string>Sky</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Trees</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Road</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolButton_2">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>DisplayWidget</class>
+ <extends>QWidget</extends>
+ <header>displaywidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>shapeComboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>Window</receiver>
+ <slot>updateShape(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>288</x>
+ <y>232</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>336</x>
+ <y>234</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>colorButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Window</receiver>
+ <slot>updateColor()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>301</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>337</x>
+ <y>267</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>shapeComboBox_2</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>Window</receiver>
+ <slot>updateBackground(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>306</x>
+ <y>299</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>337</x>
+ <y>311</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>toolButton_2</sender>
+ <signal>clicked()</signal>
+ <receiver>Window</receiver>
+ <slot>saveSvg()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>298</x>
+ <y>336</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>307</x>
+ <y>348</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>updateBackground(int)</slot>
+ <slot>updateColor()</slot>
+ <slot>updateShape(int)</slot>
+ <slot>saveSvg()</slot>
+ </slots>
+</ui>
diff --git a/util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/main.cpp b/examples/painting/svggenerator/main.cpp
index f67c971..fa8b0ab 100644
--- a/util/scripts/mac-binary/install/xcode/integration/templates/Project Templates/Application/Qt Application/main.cpp
+++ b/examples/painting/svggenerator/main.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,15 +38,15 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <QtGui/QtGui>
-int main(int argc, char **argv)
-{
- QApplication a(argc, argv);
+#include <QApplication>
- QLabel label;
- label.setText("Hello world!");
- label.show();
+#include "window.h"
- return a.exec();
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Window window;
+ window.show();
+ return app.exec();
}
diff --git a/examples/painting/svggenerator/resources/shapes.dat b/examples/painting/svggenerator/resources/shapes.dat
new file mode 100644
index 0000000..d9b981e
--- /dev/null
+++ b/examples/painting/svggenerator/resources/shapes.dat
Binary files differ
diff --git a/examples/painting/svggenerator/svggenerator.pro b/examples/painting/svggenerator/svggenerator.pro
new file mode 100644
index 0000000..4d08ba4
--- /dev/null
+++ b/examples/painting/svggenerator/svggenerator.pro
@@ -0,0 +1,15 @@
+FORMS = forms/window.ui
+HEADERS = displaywidget.h \
+ window.h
+RESOURCES = svggenerator.qrc
+SOURCES = displaywidget.cpp \
+ main.cpp \
+ window.cpp
+
+QT += svg
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/painting/svggenerator
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS svggenerator.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/painting/svggenerator
+INSTALLS += target sources
diff --git a/examples/painting/svggenerator/svggenerator.qrc b/examples/painting/svggenerator/svggenerator.qrc
new file mode 100644
index 0000000..061d1f6
--- /dev/null
+++ b/examples/painting/svggenerator/svggenerator.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/shapes.dat</file>
+</qresource>
+</RCC>
diff --git a/examples/painting/svggenerator/window.cpp b/examples/painting/svggenerator/window.cpp
new file mode 100644
index 0000000..1965604
--- /dev/null
+++ b/examples/painting/svggenerator/window.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QColorDialog>
+#include <QFileDialog>
+#include <QPainter>
+#include <QSvgGenerator>
+#include "window.h"
+#include "displaywidget.h"
+
+Window::Window(QWidget *parent)
+ : QWidget(parent)
+{
+ setupUi(this);
+}
+
+void Window::updateBackground(int background)
+{
+ displayWidget->setBackground(DisplayWidget::Background(background));
+}
+
+void Window::updateColor()
+{
+ QColor color = QColorDialog::getColor(displayWidget->color());
+ if (color.isValid())
+ displayWidget->setColor(color);
+}
+
+void Window::updateShape(int shape)
+{
+ displayWidget->setShape(DisplayWidget::Shape(shape));
+}
+
+//! [save SVG]
+void Window::saveSvg()
+{
+ QString newPath = QFileDialog::getSaveFileName(this, tr("Save SVG"),
+ path, tr("SVG files (*.svg)"));
+
+ if (newPath.isEmpty())
+ return;
+
+ path = newPath;
+
+//![configure SVG generator]
+ QSvgGenerator generator;
+ generator.setFileName(path);
+ generator.setSize(QSize(200, 200));
+ generator.setViewBox(QRect(0, 0, 200, 200));
+ generator.setTitle(tr("SVG Generator Example Drawing"));
+ generator.setDescription(tr("An SVG drawing created by the SVG Generator "
+ "Example provided with Qt."));
+//![configure SVG generator]
+//![begin painting]
+ QPainter painter;
+ painter.begin(&generator);
+//![begin painting]
+ displayWidget->paint(painter);
+//![end painting]
+ painter.end();
+//![end painting]
+}
+//! [save SVG]
diff --git a/util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.h b/examples/painting/svggenerator/window.h
index c48011d4..4bc4d22 100644
--- a/util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.h
+++ b/examples/painting/svggenerator/window.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,25 +38,29 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-/*
- * «FILENAME»
- * «PROJECTNAME»
- *
- * Created by «FULLUSERNAME» on «DATE».
- * Copyright (c) «YEAR» «ORGANIZATIONNAME». All rights reserved.
- *
- */
-#ifndef «FILEBASENAME»__HEADER
+#ifndef WINDOW_H
+#define WINDOW_H
-#include <QtGui/QtGui>
+#include "ui_window.h"
-class «FILEBASENAME» : public QWidget
+//! [Window class definition]
+class Window : public QWidget, private Ui::Window
{
Q_OBJECT
+
public:
- «FILEBASENAME»(QWidget *parent=0);
- ~«FILEBASENAME»();
+ Window(QWidget *parent = 0);
+
+public slots:
+ void saveSvg();
+ void updateBackground(int background);
+ void updateColor();
+ void updateShape(int shape);
+
+private:
+ QString path;
};
+//! [Window class definition]
-#endif //«FILEBASENAME»__HEADER
+#endif
diff --git a/util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.cpp b/examples/threads/queuedcustomtype/block.cpp
index d790000..1a14f09 100644
--- a/util/scripts/mac-binary/install/xcode/integration/templates/File Templates/Qt/C++ Class.pbfiletemplate/class.cpp
+++ b/examples/threads/queuedcustomtype/block.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,24 +38,37 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-/*
- * «FILENAME»
- * «PROJECTNAME»
- *
- * Created by «FULLUSERNAME» on «DATE».
- * Copyright (c) «YEAR» «ORGANIZATIONNAME». All rights reserved.
- *
- */
-#include "«FILEBASENAME».h"
+#include <QColor>
+#include <QRect>
+#include "block.h"
-«FILEBASENAME»::«FILEBASENAME»(QWidget *parent) : QWidget(parent)
+Block::Block()
{
+}
+Block::Block(const Block &other)
+{
+ m_rect = other.m_rect;
+ m_color = other.m_color;
+}
+Block::~Block()
+{
}
-«FILEBASENAME»::~«FILEBASENAME»()
+Block::Block(const QRect &rect, const QColor &color)
{
+ m_rect = rect;
+ m_color = color;
+}
+QColor Block::color() const
+{
+ return m_color;
+}
+
+QRect Block::rect() const
+{
+ return m_rect;
}
diff --git a/util/scripts/mac-binary/package/InstallerPane/helpfulfunc.h b/examples/threads/queuedcustomtype/block.h
index b774f60..2a75529 100644
--- a/util/scripts/mac-binary/package/InstallerPane/helpfulfunc.h
+++ b/examples/threads/queuedcustomtype/block.h
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,25 +38,34 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-/*
- * helpfulfunc.h
- * InstallerPane
- *
- * Created by Trenton Schulz on 7/27/05.
- * Copyright 2005 __MyCompanyName__. All rights reserved.
- *
- */
-#ifndef HELPFULFUNC_H
-#define HELPFULFUNC_H
+#ifndef BLOCK_H
+#define BLOCK_H
-#import <stdio.h>
+#include <QColor>
+#include <QDebug>
+#include <QMetaType>
+#include <QRect>
-extern const char LicenseeString[];
-extern const char LicenseKeyExtString[];
+//! [custom type definition and meta-type declaration]
+class Block
+{
+public:
+ Block();
+ Block(const Block &other);
+ ~Block();
-enum LicenseValues { LicenseOK = 0, InvalidLicense, InvalidProduct, InvalidPlatform, InvalidType, LicenseExpired };
+ Block(const QRect &rect, const QColor &color);
-int validateLicense(const char *string);
+ QColor color() const;
+ QRect rect() const;
-#endif // HELPFULFUNC_H \ No newline at end of file
+private:
+ QRect m_rect;
+ QColor m_color;
+};
+
+Q_DECLARE_METATYPE(Block);
+//! [custom type definition and meta-type declaration]
+
+#endif
diff --git a/examples/threads/queuedcustomtype/main.cpp b/examples/threads/queuedcustomtype/main.cpp
new file mode 100644
index 0000000..93dab49
--- /dev/null
+++ b/examples/threads/queuedcustomtype/main.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QPainter>
+#include <QTime>
+#include "block.h"
+#include "window.h"
+
+QImage createImage(int width, int height)
+{
+ QImage image(width, height, QImage::Format_RGB16);
+ QPainter painter;
+ QPen pen;
+ pen.setStyle(Qt::NoPen);
+ QBrush brush(Qt::blue);
+
+ painter.begin(&image);
+ painter.fillRect(image.rect(), brush);
+ brush.setColor(Qt::white);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+
+ static const QPointF points1[3] = {
+ QPointF(4, 4),
+ QPointF(7, 4),
+ QPointF(5.5, 1)
+ };
+
+ static const QPointF points2[3] = {
+ QPointF(1, 4),
+ QPointF(7, 4),
+ QPointF(10, 10)
+ };
+
+ static const QPointF points3[3] = {
+ QPointF(4, 4),
+ QPointF(10, 4),
+ QPointF(1, 10)
+ };
+
+ painter.setWindow(0, 0, 10, 10);
+
+ int x = 0;
+ int y = 0;
+ int starWidth = image.width()/3;
+ int starHeight = image.height()/3;
+
+ QRect rect(x, y, starWidth, starHeight);
+
+ for (int i = 0; i < 9; ++i) {
+
+ painter.setViewport(rect);
+ painter.drawPolygon(points1, 3);
+ painter.drawPolygon(points2, 3);
+ painter.drawPolygon(points3, 3);
+
+ if (i % 3 == 2) {
+ y = y + starHeight;
+ rect.moveTop(y);
+
+ x = 0;
+ rect.moveLeft(x);
+
+ } else {
+ x = x + starWidth;
+ rect.moveLeft(x);
+ }
+ }
+
+ painter.end();
+ return image;
+}
+
+//! [main function] //! [main start]
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+//! [main start] //! [register meta-type for queued communications]
+ qRegisterMetaType<Block>();
+//! [register meta-type for queued communications]
+ qsrand(QTime::currentTime().elapsed());
+
+ Window window;
+ window.show();
+
+ window.loadImage(createImage(256, 256));
+//! [main finish]
+ return app.exec();
+}
+//! [main finish] //! [main function]
diff --git a/examples/threads/queuedcustomtype/queuedcustomtype.pro b/examples/threads/queuedcustomtype/queuedcustomtype.pro
new file mode 100644
index 0000000..6f39121
--- /dev/null
+++ b/examples/threads/queuedcustomtype/queuedcustomtype.pro
@@ -0,0 +1,7 @@
+HEADERS = block.h \
+ renderthread.h \
+ window.h
+SOURCES = main.cpp \
+ block.cpp \
+ renderthread.cpp \
+ window.cpp
diff --git a/examples/threads/queuedcustomtype/renderthread.cpp b/examples/threads/queuedcustomtype/renderthread.cpp
new file mode 100644
index 0000000..052dd39
--- /dev/null
+++ b/examples/threads/queuedcustomtype/renderthread.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderthread.h"
+
+RenderThread::RenderThread(QObject *parent)
+ : QThread(parent)
+{
+ m_abort = false;
+}
+
+RenderThread::~RenderThread()
+{
+ mutex.lock();
+ m_abort = true;
+ mutex.unlock();
+
+ wait();
+}
+
+//![processing the image (start)]
+void RenderThread::processImage(const QImage &image)
+{
+ if (image.isNull())
+ return;
+
+ m_image = image;
+ m_abort = false;
+ start();
+}
+
+void RenderThread::run()
+{
+ int size = qMax(m_image.width()/20, m_image.height()/20);
+ for (int s = size; s > 0; --s) {
+ for (int c = 0; c < 400; ++c) {
+//![processing the image (start)]
+ int x1 = qMax(0, (qrand() % m_image.width()) - s/2);
+ int x2 = qMin(x1 + s/2 + 1, m_image.width());
+ int y1 = qMax(0, (qrand() % m_image.height()) - s/2);
+ int y2 = qMin(y1 + s/2 + 1, m_image.height());
+ int n = 0;
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+ for (int i = y1; i < y2; ++i) {
+ for (int j = x1; j < x2; ++j) {
+ QRgb pixel = m_image.pixel(j, i);
+ red += qRed(pixel);
+ green += qGreen(pixel);
+ blue += qBlue(pixel);
+ n += 1;
+ }
+ }
+//![processing the image (finish)]
+ Block block(QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1),
+ QColor(red/n, green/n, blue/n));
+ emit sendBlock(block);
+ if (m_abort)
+ return;
+ msleep(10);
+ }
+ }
+}
+//![processing the image (finish)]
+
+void RenderThread::stopProcess()
+{
+ mutex.lock();
+ m_abort = true;
+ mutex.unlock();
+}
diff --git a/examples/threads/queuedcustomtype/renderthread.h b/examples/threads/queuedcustomtype/renderthread.h
new file mode 100644
index 0000000..9c7f049
--- /dev/null
+++ b/examples/threads/queuedcustomtype/renderthread.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERTHREAD_H
+#define RENDERTHREAD_H
+
+#include <QImage>
+#include <QMutex>
+#include <QThread>
+#include "block.h"
+
+//! [RenderThread class definition]
+class RenderThread : public QThread
+{
+ Q_OBJECT
+
+public:
+ RenderThread(QObject *parent = 0);
+ ~RenderThread();
+
+ void processImage(const QImage &image);
+
+signals:
+ void sendBlock(const Block &block);
+
+public slots:
+ void stopProcess();
+
+protected:
+ void run();
+
+private:
+ bool m_abort;
+ QImage m_image;
+ QMutex mutex;
+};
+//! [RenderThread class definition]
+
+#endif
diff --git a/examples/threads/queuedcustomtype/window.cpp b/examples/threads/queuedcustomtype/window.cpp
new file mode 100644
index 0000000..7282e0c
--- /dev/null
+++ b/examples/threads/queuedcustomtype/window.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include "window.h"
+
+//! [Window constructor start]
+Window::Window()
+{
+ thread = new RenderThread();
+//! [Window constructor start] //! [set up widgets and connections]
+
+ label = new QLabel();
+ label->setAlignment(Qt::AlignCenter);
+
+ loadButton = new QPushButton(tr("&Load image..."));
+ resetButton = new QPushButton(tr("&Stop"));
+ resetButton->setEnabled(false);
+
+ connect(loadButton, SIGNAL(clicked()), this, SLOT(loadImage()));
+ connect(resetButton, SIGNAL(clicked()), thread, SLOT(stopProcess()));
+ connect(thread, SIGNAL(finished()), this, SLOT(resetUi()));
+//! [set up widgets and connections] //! [connecting signal with custom type]
+ connect(thread, SIGNAL(sendBlock(Block)), this, SLOT(addBlock(Block)));
+//! [connecting signal with custom type]
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(loadButton);
+ buttonLayout->addWidget(resetButton);
+ buttonLayout->addStretch();
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(label);
+ layout->addLayout(buttonLayout);
+
+//! [Window constructor finish]
+ setWindowTitle(tr("Queued Custom Type"));
+}
+//! [Window constructor finish]
+
+void Window::loadImage()
+{
+ QStringList formats;
+ foreach (QByteArray format, QImageReader::supportedImageFormats())
+ if (format.toLower() == format)
+ formats.append("*." + format);
+
+ QString newPath = QFileDialog::getOpenFileName(this, tr("Open Image"),
+ path, tr("Image files (%1)").arg(formats.join(" ")));
+
+ if (newPath.isEmpty())
+ return;
+
+ QImage image(newPath);
+ if (!image.isNull()) {
+ loadImage(image);
+ path = newPath;
+ }
+}
+
+void Window::loadImage(const QImage &image)
+{
+ QDesktopWidget desktop;
+ QImage useImage;
+ QRect space = desktop.availableGeometry();
+ if (image.width() > 0.75*space.width() || image.height() > 0.75*space.height())
+ useImage = image.scaled(0.75*space.width(), 0.75*space.height(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ else
+ useImage = image;
+
+ pixmap = QPixmap(useImage.width(), useImage.height());
+ pixmap.fill(qRgb(255, 255, 255));
+ label->setPixmap(pixmap);
+ loadButton->setEnabled(false);
+ resetButton->setEnabled(true);
+ thread->processImage(useImage);
+}
+
+//! [Adding blocks to the display]
+void Window::addBlock(const Block &block)
+{
+ QColor color = block.color();
+ color.setAlpha(64);
+
+ QPainter painter;
+ painter.begin(&pixmap);
+ painter.fillRect(block.rect(), color);
+ painter.end();
+ label->setPixmap(pixmap);
+}
+//! [Adding blocks to the display]
+
+void Window::resetUi()
+{
+ loadButton->setEnabled(true);
+ resetButton->setEnabled(false);
+}
diff --git a/examples/threads/queuedcustomtype/window.h b/examples/threads/queuedcustomtype/window.h
new file mode 100644
index 0000000..c0ed280
--- /dev/null
+++ b/examples/threads/queuedcustomtype/window.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+#include "renderthread.h"
+
+class QLabel;
+class QPushButton;
+
+//! [Window class definition]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+ void loadImage(const QImage &image);
+
+public slots:
+ void addBlock(const Block &block);
+
+private slots:
+ void loadImage();
+ void resetUi();
+
+private:
+ QLabel *label;
+ QPixmap pixmap;
+ QPushButton *loadButton;
+ QPushButton *resetButton;
+ QString path;
+ RenderThread *thread;
+};
+//! [Window class definition]
+
+#endif
diff --git a/examples/tools/customtype/customtype.pro b/examples/tools/customtype/customtype.pro
new file mode 100644
index 0000000..3079964
--- /dev/null
+++ b/examples/tools/customtype/customtype.pro
@@ -0,0 +1,3 @@
+HEADERS = message.h
+SOURCES = main.cpp \
+ message.cpp
diff --git a/util/scripts/mac-binary/package/keydecoder/main.cpp b/examples/tools/customtype/main.cpp
index 3aa37f9..e8f4265 100644
--- a/util/scripts/mac-binary/package/keydecoder/main.cpp
+++ b/examples/tools/customtype/main.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,17 +38,37 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <cstdio>
-#include "../InstallerPane/keydec.h"
-int main(int argc, char **argv)
+#include <QCoreApplication>
+#include <QVariant>
+#include "message.h"
+
+int main(int argc, char *argv[])
{
- if (argc != 2)
- return 1;
- KeyDecoder key(argv[1]);
- if (!key.IsValid())
- return 2;
- CDate date = key.getExpiryDate();
- fprintf(stdout, "%04d-%02d-%02d\n", date.year(), date.month(), date.day());
+ QCoreApplication app(argc, argv);
+ QStringList headers;
+ headers << "Subject: Hello World"
+ << "From: qt-info@nokia.com";
+ QString body = "This is a test.\r\n";
+
+//! [printing a custom type]
+ Message message(body, headers);
+ qDebug() << "Original:" << message;
+//! [printing a custom type]
+
+//! [storing a custom value]
+ QVariant stored;
+ stored.setValue(message);
+//! [storing a custom value]
+
+ qDebug() << "Stored:" << stored;
+
+//! [retrieving a custom value]
+ Message retrieved = stored.value<Message>();
+ qDebug() << "Retrieved:" << retrieved;
+ retrieved = qVariantValue<Message>(stored);
+ qDebug() << "Retrieved:" << retrieved;
+//! [retrieving a custom value]
+
return 0;
}
diff --git a/examples/tools/customtype/message.cpp b/examples/tools/customtype/message.cpp
new file mode 100644
index 0000000..b6fd536
--- /dev/null
+++ b/examples/tools/customtype/message.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "message.h"
+
+//! [Message class implementation]
+Message::Message()
+{
+}
+
+Message::Message(const Message &other)
+{
+ m_body = other.m_body;
+ m_headers = other.m_headers;
+}
+
+Message::~Message()
+{
+}
+//! [Message class implementation]
+
+Message::Message(const QString &body, const QStringList &headers)
+{
+ m_body = body;
+ m_headers = headers;
+}
+
+//! [custom type streaming operator]
+QDebug &operator<<(QDebug &dbg, const Message &message)
+{
+ QStringList pieces = message.body().split("\r\n", QString::SkipEmptyParts);
+ if (pieces.isEmpty())
+ dbg.nospace() << "Message()";
+ else if (pieces.size() == 1)
+ dbg.nospace() << "Message(" << pieces.first() << ")";
+ else
+ dbg.nospace() << "Message(" << pieces.first() << " ...)";
+ return dbg.maybeSpace();
+}
+//! [custom type streaming operator]
+
+//! [getter functions]
+QString Message::body() const
+{
+ return m_body;
+}
+
+QStringList Message::headers() const
+{
+ return m_headers;
+}
+//! [getter functions]
diff --git a/examples/tools/customtype/message.h b/examples/tools/customtype/message.h
new file mode 100644
index 0000000..2620557
--- /dev/null
+++ b/examples/tools/customtype/message.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGE_H
+#define MESSAGE_H
+
+#include <QDebug>
+#include <QMetaType>
+#include <QStringList>
+
+//! [custom type definition]
+class Message
+{
+public:
+ Message();
+ Message(const Message &other);
+ ~Message();
+
+ Message(const QString &body, const QStringList &headers);
+
+ QString body() const;
+ QStringList headers() const;
+
+private:
+ QString m_body;
+ QStringList m_headers;
+};
+//! [custom type definition]
+
+//! [custom type meta-type declaration]
+Q_DECLARE_METATYPE(Message);
+//! [custom type meta-type declaration]
+
+//! [custom type streaming operator]
+QDebug &operator<<(QDebug &dbg, const Message &message);
+//! [custom type streaming operator]
+
+#endif
diff --git a/examples/tools/customtypesending/customtypesending.pro b/examples/tools/customtypesending/customtypesending.pro
new file mode 100644
index 0000000..b8b2aaf
--- /dev/null
+++ b/examples/tools/customtypesending/customtypesending.pro
@@ -0,0 +1,5 @@
+HEADERS = message.h \
+ window.h
+SOURCES = main.cpp \
+ message.cpp \
+ window.cpp
diff --git a/examples/tools/customtypesending/main.cpp b/examples/tools/customtypesending/main.cpp
new file mode 100644
index 0000000..336f3d8
--- /dev/null
+++ b/examples/tools/customtypesending/main.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "message.h"
+#include "window.h"
+
+//! [main function]
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ Window window1;
+ QStringList headers;
+ headers << "Subject: Hello World"
+ << "From: qt-info@nokia.com";
+ QString body = "This is a test.\r\n";
+ Message message(body, headers);
+ window1.setMessage(message);
+
+ Window window2;
+ QObject::connect(&window1, SIGNAL(messageSent(Message)),
+ &window2, SLOT(setMessage(Message)));
+ QObject::connect(&window2, SIGNAL(messageSent(Message)),
+ &window1, SLOT(setMessage(Message)));
+ window1.show();
+ window2.show();
+ return app.exec();
+}
+//! [main function]
diff --git a/util/scripts/mac-binary/package/InstallerPane/InstallerSecionSection.h b/examples/tools/customtypesending/message.cpp
index 6b3abbe..6992804 100644
--- a/util/scripts/mac-binary/package/InstallerPane/InstallerSecionSection.h
+++ b/examples/tools/customtypesending/message.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,19 +38,35 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-//
-// InstallerSecionSection.h
-// InstallerPane
-//
-// Created by Trenton Schulz on 7/27/05.
-// Copyright 2005 __MyCompanyName__. All rights reserved.
-//
-#import <Cocoa/Cocoa.h>
-#include <InstallerPlugins/InstallerSection.h>
+#include "message.h"
-@interface InstallerSecionSection : InstallerSection {
+Message::Message()
+{
+}
+
+Message::Message(const Message &other)
+{
+ m_body = other.m_body;
+ m_headers = other.m_headers;
+}
+
+Message::~Message()
+{
+}
+
+Message::Message(const QString &body, const QStringList &headers)
+{
+ m_body = body;
+ m_headers = headers;
+}
+QString Message::body() const
+{
+ return m_body;
}
-@end
+QStringList Message::headers() const
+{
+ return m_headers;
+}
diff --git a/examples/tools/customtypesending/message.h b/examples/tools/customtypesending/message.h
new file mode 100644
index 0000000..55f9568
--- /dev/null
+++ b/examples/tools/customtypesending/message.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGE_H
+#define MESSAGE_H
+
+#include <QDebug>
+#include <QMetaType>
+#include <QStringList>
+
+//! [custom type definition]
+class Message
+{
+public:
+ Message();
+ Message(const Message &other);
+ ~Message();
+
+ Message(const QString &body, const QStringList &headers);
+
+ QString body() const;
+ QStringList headers() const;
+
+private:
+ QString m_body;
+ QStringList m_headers;
+};
+//! [custom type definition]
+
+//! [custom type meta-type declaration]
+Q_DECLARE_METATYPE(Message);
+//! [custom type meta-type declaration]
+
+#endif
diff --git a/util/scripts/win-binary/nsis/qtnsisext/binpatch.h b/examples/tools/customtypesending/window.cpp
index 7cbc6a5..be79518 100644
--- a/util/scripts/win-binary/nsis/qtnsisext/binpatch.h
+++ b/examples/tools/customtypesending/window.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
-** This file is part of the utils of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -38,44 +38,43 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef BINPATCH_H
-#define BINPATCH_H
-#include <string.h>
+#include <QtGui>
+#include "window.h"
-typedef unsigned long ulong;
-typedef unsigned int uint;
-
-class BinPatch
+//! [Window constructor]
+Window::Window()
{
-public:
- BinPatch(const char *file)
- : useLength(false), insertReplace(false)
- {
- strcpy(endTokens, "");
- strcpy(fileName, file);
- }
+ editor = new QTextEdit();
+ QPushButton *sendButton = new QPushButton(tr("&Send message"));
- void enableUseLength(bool enabled)
- { useLength = enabled; }
- void enableInsertReplace(bool enabled)
- { insertReplace = enabled; }
- void setEndTokens(const char *tokens)
- { strcpy(endTokens, tokens); }
+ connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage()));
- bool patch(const char *oldstr, const char *newstr);
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(sendButton);
+ buttonLayout->addStretch();
-private:
- long getBufferStringLength(char *data, char *end);
- bool endsWithTokens(const char *data);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(editor);
+ layout->addLayout(buttonLayout);
- bool patchHelper(char *inbuffer, const char *oldstr,
- const char *newstr, size_t len, long *rw);
+ setWindowTitle(tr("Custom Type Sending"));
+}
+//! [Window constructor]
- bool useLength;
- bool insertReplace;
- char endTokens[1024];
- char fileName[1024];
-};
+//! [sending a message]
+void Window::sendMessage()
+{
+ thisMessage = Message(editor->toPlainText(), thisMessage.headers());
+ emit messageSent(thisMessage);
+}
+//! [sending a message]
-#endif \ No newline at end of file
+//! [receiving a message]
+void Window::setMessage(const Message &message)
+{
+ thisMessage = message;
+ editor->setPlainText(thisMessage.body());
+}
+//! [receiving a message]
diff --git a/examples/tools/customtypesending/window.h b/examples/tools/customtypesending/window.h
new file mode 100644
index 0000000..cbe9775
--- /dev/null
+++ b/examples/tools/customtypesending/window.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the examples 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+#include "message.h"
+
+class QTextEdit;
+
+//! [Window class definition]
+class Window : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Window();
+
+signals:
+ void messageSent(const Message &message);
+
+public slots:
+ void setMessage(const Message &message);
+
+private slots:
+ void sendMessage();
+
+private:
+ Message thisMessage;
+ QTextEdit *editor;
+};
+//! [Window class definition]
+
+#endif
diff --git a/examples/tutorials/addressbook/README b/examples/tutorials/addressbook/README
index 2d528b5..9b7f908 100644
--- a/examples/tutorials/addressbook/README
+++ b/examples/tutorials/addressbook/README
@@ -4,7 +4,7 @@ Qt documentation, which can be viewed using Qt Assistant or a Web browser.
The tutorial is also available online at
-http://doc.trolltech.com/4.4/tutorial.html
+http://doc.trolltech.com/tutorial.html
All programs corresponding to the chapters in the tutorial should
automatically be built when Qt is compiled, or will be provided as
diff --git a/examples/widgets/movie/movie.pro b/examples/widgets/movie/movie.pro
index b5f0a7a..1c7cbae 100644
--- a/examples/widgets/movie/movie.pro
+++ b/examples/widgets/movie/movie.pro
@@ -4,6 +4,6 @@ SOURCES = main.cpp \
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie
-sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro movies
+sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro animation.mng
sources.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie
INSTALLS += target sources
diff --git a/examples/xml/xmlstreamlint/main.cpp b/examples/xml/xmlstreamlint/main.cpp
index e006c82..6063b84 100644
--- a/examples/xml/xmlstreamlint/main.cpp
+++ b/examples/xml/xmlstreamlint/main.cpp
@@ -46,7 +46,7 @@
#include <QXmlStreamReader>
/*
- This class exists for the solve purpose of creating a translation context.
+ This class exists for the sole purpose of creating a translation context.
*/
class XmlStreamLint
{
diff --git a/examples/xmlpatterns/trafficinfo/mainwindow.cpp b/examples/xmlpatterns/trafficinfo/mainwindow.cpp
index c4ca731..1f754d5 100644
--- a/examples/xmlpatterns/trafficinfo/mainwindow.cpp
+++ b/examples/xmlpatterns/trafficinfo/mainwindow.cpp
@@ -71,7 +71,7 @@ MainWindow::MainWindow()
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTimeInformation()));
- timer->start(1000*60);
+ timer->start(1000*60*5);
const QSettings settings("Qt Software", "trafficinfo");
m_station = StationInformation(settings.value("stationId", "03012130").toString(),
diff --git a/mkspecs/features/include_source_dir.prf b/mkspecs/features/include_source_dir.prf
new file mode 100644
index 0000000..8794998
--- /dev/null
+++ b/mkspecs/features/include_source_dir.prf
@@ -0,0 +1 @@
+!equals(_PRO_FILE_PWD_, $$OUT_PWD):INCLUDEPATH *= .
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf
index faa9871..7c4ff28 100644
--- a/mkspecs/features/moc.prf
+++ b/mkspecs/features/moc.prf
@@ -8,31 +8,46 @@ isEmpty(MOC_DIR):MOC_DIR = .
isEmpty(QMAKE_H_MOD_MOC):QMAKE_H_MOD_MOC = moc_
isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc
-# This function on Windows puts the includes into a .inc file which moc will read, if the project
-# has more than 30 includes. We do this to overcome a command-line limit on Win < XP
-# Otherwise the function simply returns the normal command-line for moc
-defineReplace(mocCmd) {
- win32:count($$list($$INCPATH), 40, >) {
- EOC = $$escape_expand(\n\t)
+# On Windows, put the includes into a .inc file which moc will read, if the project
+# has too many includes. We do this to overcome a command-line limit on Win < XP
+INCLUDETEMP=
+WIN_INCLUDETEMP=
+win32:count($$list($$INCPATH), 40, >) {
+ INCLUDETEMP = $$MOC_DIR/mocinclude.tmp
+
+ # Remove any existing mocinclude.tmp when qmake runs
+ WIN_INCLUDETEMP=$$INCLUDETEMP
+ WIN_INCLUDETEMP~=s,/,\,g
+ system($$QMAKE_DEL_FILE $$WIN_INCLUDETEMP > NUL 2>&1)
+
+ EOC = $$escape_expand(\n\t)
+
+ if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) {
+ # the VCPROJ generator will replace the \r\h with the coded \r\n: &#x0d;&#x0a;
+ # No other generator understands the \h
+ if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h)
+ else: EOC = $$escape_expand(\\)$$escape_expand(\n\t)
+ }
+
+ unset(INCFILELIST)
+ RET =
+ for(incfile, $$list($$INCPATH)) {
+ INCFILELIST = -I$$incfile
+ isEmpty(RET): RET += @echo $$INCFILELIST> $$WIN_INCLUDETEMP $$EOC
+ else: RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC
+ }
+ !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC
- if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) {
- # the VCPROJ generator will replace the \r\h with the coded \r\n: &#x0d;&#x0a;
- # No other generator understands the \h
- if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h)
- else: EOC = $$escape_expand(\\)$$escape_expand(\n\t)
- }
+ build_pass|isEmpty(BUILDS) {
+ mocinclude.target = $$INCLUDETEMP
+ mocinclude.commands = $$RET
+ QMAKE_EXTRA_TARGETS += mocinclude
+ }
+}
- INCLUDETEMP = mocinclude.tmp
- unset(INCFILELIST)
- RET =
- for(incfile, $$list($$INCPATH)) {
- INCFILELIST = -I$$incfile
- isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC
- else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC
- }
- !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC
- RET += $$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2
- return($$RET)
+defineReplace(mocCmd) {
+ !isEmpty(WIN_INCLUDETEMP) {
+ return($$QMAKE_MOC $(DEFINES) @$$WIN_INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2)
}
return($$QMAKE_MOC $(DEFINES) $(INCPATH) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2)
}
@@ -45,6 +60,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK
moc_header.input = HEADERS
moc_header.variable_out = SOURCES
moc_header.name = MOC ${QMAKE_FILE_IN}
+!isEmpty(INCLUDETEMP):moc_header.depends += $$INCLUDETEMP
silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands
QMAKE_EXTRA_COMPILERS += moc_header
INCREDIBUILD_XGE += moc_header
@@ -56,12 +72,23 @@ moc_source.commands = ${QMAKE_FUNC_mocCmd}
moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}
moc_source.input = SOURCES OBJECTIVE_SOURCES
moc_source.name = MOC ${QMAKE_FILE_IN}
+!isEmpty(INCLUDETEMP):moc_source.depends += $$INCLUDETEMP
silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands
QMAKE_EXTRA_COMPILERS += moc_source
INCREDIBUILD_XGE += moc_source
#make sure we can include these files
-INCLUDEPATH += $$MOC_DIR
+moc_dir_short = $$MOC_DIR
+win32:moc_dir_short ~= s,^.:,/,
+contains(moc_dir_short, ^[/\\\\].*):INCLUDEPATH += $$MOC_DIR
+else:INCLUDEPATH += $$OUT_PWD/$$MOC_DIR
+
+# Backwards compatibility: Make shadow builds with default MOC_DIR work
+# if the user did not add the source dir explicitly.
+equals(MOC_DIR, .) {
+ CONFIG -= include_source_dir
+ CONFIG = include_source_dir $$CONFIG
+}
#auto depend on moc
unix:!no_mocdepend {
diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf
index 885fad7..0c7fb1b 100644
--- a/mkspecs/features/uic.prf
+++ b/mkspecs/features/uic.prf
@@ -34,7 +34,17 @@ isEmpty(QMAKE_MOD_UIC):QMAKE_MOD_UIC = ui_
INCREDIBUILD_XGE += uic
}
-INCLUDEPATH += $$UI_HEADERS_DIR
+ui_dir_short = $$UI_HEADERS_DIR
+win32:ui_dir_short ~= s,^.:,/,
+contains(ui_dir_short, ^[/\\\\].*):INCLUDEPATH += $$UI_HEADERS_DIR
+else:INCLUDEPATH += $$OUT_PWD/$$UI_HEADERS_DIR
+
+# Backwards compatibility: Make shadow builds with default UI_DIR work
+# if the user did not add the source dir explicitly.
+equals(UI_DIR, .) {
+ CONFIG -= include_source_dir
+ CONFIG = include_source_dir $$CONFIG
+}
uic3 {
isEmpty(FORMS3) {
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index daaae4c..473a625 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -719,6 +719,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
for(QStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit)
mkt << " " << "-I" << escapeFilePath((*incit));
}
+ if(!project->isEmpty("QMAKE_FRAMEWORKPATH_FLAGS"))
+ mkt << " " << var("QMAKE_FRAMEWORKPATH_FLAGS");
mkt << endl;
mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 24e030e..67e5bfb 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -1492,7 +1492,7 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const
val += project->values(varname);
}
if(val.isEmpty() && var.startsWith(QLatin1String("QMAKE_VAR_FIRST_"))) {
- const QString varname = var.mid(12);
+ const QString varname = var.mid(16);
val += project->first(varname);
}
@@ -2735,16 +2735,9 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q
ret.prepend(pwd);
ret = Option::fixPathToTargetOS(ret, false, canon);
} else { //fix it..
- QString qfile(Option::fixPathToLocalOS(ret, true, canon)), in_dir(in_d), out_dir(out_d);
+ QString out_dir = QDir(Option::output_dir).absoluteFilePath(out_d);
+ QString in_dir = QDir(pwd).absoluteFilePath(in_d);
{
- if(out_dir.isNull() || QDir::isRelativePath(out_dir))
- out_dir.prepend(Option::output_dir + "/");
- else if(out_dir == ".")
- out_dir = pwd;
- if(in_dir.isEmpty() || QDir::isRelativePath(in_dir))
- in_dir.prepend(pwd);
- else if(in_dir == ".")
- in_dir = pwd;
QFileInfo in_fi(fileInfo(in_dir));
if(in_fi.exists())
in_dir = in_fi.canonicalFilePath();
@@ -2753,6 +2746,7 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q
out_dir = out_fi.canonicalFilePath();
}
+ QString qfile(Option::fixPathToLocalOS(ret, true, canon));
QFileInfo qfileinfo(fileInfo(qfile));
if(out_dir != in_dir || !qfileinfo.isRelative()) {
if(qfileinfo.isRelative()) {
@@ -2806,7 +2800,7 @@ MakefileGenerator::fileFixify(const QString& file, const QString &out_d, const Q
}
if(ret.isEmpty())
ret = ".";
- debug_msg(3, "Fixed[%d] %s :: to :: %s [%s::%s] [%s::%s]", fix, orig_file.toLatin1().constData(),
+ debug_msg(3, "Fixed[%d,%d] %s :: to :: %s [%s::%s] [%s::%s]", fix, canon, orig_file.toLatin1().constData(),
ret.toLatin1().constData(), in_d.toLatin1().constData(), out_d.toLatin1().constData(),
pwd.toLatin1().constData(), Option::output_dir.toLatin1().constData());
cache->insert(cacheKey, ret);
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index a26a247..cf09a6a 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -109,7 +109,7 @@ protected:
struct SubTarget
{
QString name;
- QString in_directory, out_directory;
+ QString in_directory, out_directory;
QString profile, target, makefile;
QStringList depends;
};
@@ -183,8 +183,8 @@ protected:
void filterIncludedFiles(const QString &);
virtual void processSources() {
- filterIncludedFiles("SOURCES");
- filterIncludedFiles("GENERATED_SOURCES");
+ filterIncludedFiles("SOURCES");
+ filterIncludedFiles("GENERATED_SOURCES");
}
//for cross-platform dependent directories
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index f0683a7..3f60791 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -360,7 +360,7 @@ SubdirsMetaMakefileGenerator::init()
}
--recurseDepth;
- Option::output.setFileName(old_output);
+ Option::output.setFileName(old_output);
Option::output_dir = old_output_dir;
qmake_setpwd(oldpwd);
}
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index c845b86..585ab55 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -740,7 +740,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString src = fileFixify(files[file], FileFixifyAbsolute);
if (!QFile::exists(src))
src = files[file];
- const QString dst = path + Option::dir_sep + fileInfo(files[file]).fileName();
+ src = escapeFilePath(src);
+ const QString dst = escapeFilePath(path + Option::dir_sep + fileInfo(files[file]).fileName());
t << dst << ": " << src << "\n\t"
<< mkdir_p_asstring(path) << "\n\t";
QFileInfo fi(fileInfo(files[file]));
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 4b1b66d..b5904cc 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -244,14 +244,14 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
project->variables().remove("QMAKE_RUN_CC");
QHash<QString, void*> source_directories;
- source_directories.insertMulti(".", (void*)1);
+ source_directories.insert(".", (void*)1);
QString directories[] = { QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString() };
for(int y = 0; !directories[y].isNull(); y++) {
QString dirTemp = project->first(directories[y]);
if (dirTemp.endsWith("\\"))
dirTemp.truncate(dirTemp.length()-1);
if(!dirTemp.isEmpty())
- source_directories.insertMulti(dirTemp, (void*)1);
+ source_directories.insert(dirTemp, (void*)1);
}
QString srcs[] = { QString("SOURCES"), QString("GENERATED_SOURCES"), QString() };
for(int x = 0; !srcs[x].isNull(); x++) {
@@ -262,7 +262,7 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
sep = "/";
QString dir = (*sit).section(sep, 0, -2);
if(!dir.isEmpty() && !source_directories[dir])
- source_directories.insertMulti(dir, (void*)1);
+ source_directories.insert(dir, (void*)1);
}
}
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 08159b0..8901289 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1030,7 +1030,6 @@ void VcprojGenerator::initCompilerTool()
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS"));
if(project->isActiveConfig("debug")){
// Debug version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS"));
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG"));
if((projectTarget == Application) || (projectTarget == StaticLib))
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG"));
@@ -1038,7 +1037,6 @@ void VcprojGenerator::initCompilerTool()
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG"));
} else {
// Release version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS"));
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE"));
conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
conf.compiler.PreprocessorDefinitions += "NDEBUG";
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 8d49788..eef32db 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -1105,7 +1105,7 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place, int num
}
}
}
- } else if(!parens && *(d+d_off) == QLatin1Char('}')) {
+ } else if(!parens && *(d+d_off) == QLatin1Char('}')) {
if(start_block) {
--start_block;
} else if(!scope_blocks.count()) {
diff --git a/src/3rdparty/phonon/gstreamer/audiooutput.cpp b/src/3rdparty/phonon/gstreamer/audiooutput.cpp
index fcadac2..138a7e4 100644
--- a/src/3rdparty/phonon/gstreamer/audiooutput.cpp
+++ b/src/3rdparty/phonon/gstreamer/audiooutput.cpp
@@ -42,6 +42,7 @@ AudioOutput::AudioOutput(Backend *backend, QObject *parent)
static int count = 0;
m_name = "AudioOutput" + QString::number(count++);
if (m_backend->isValid()) {
+ g_set_application_name(qApp->applicationName().toUtf8());
m_audioBin = gst_bin_new (NULL);
gst_object_ref (GST_OBJECT (m_audioBin));
gst_object_sink (GST_OBJECT (m_audioBin));
diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
index 5398f0c..74fc1b4 100644
--- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp
+++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
@@ -14,7 +14,6 @@
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-
#include <cmath>
#include <gst/interfaces/propertyprobe.h>
#include "common.h"
@@ -24,7 +23,6 @@
#include "backend.h"
#include "streamreader.h"
#include "phononsrc.h"
-
#include <QtCore>
#include <QtCore/QTimer>
#include <QtCore/QVector>
@@ -78,6 +76,9 @@ MediaObject::MediaObject(Backend *backend, QObject *parent)
, m_videoGraph(0)
, m_previousTickTime(-1)
, m_resetNeeded(false)
+ , m_autoplayTitles(true)
+ , m_availableTitles(0)
+ , m_currentTitle(1)
{
qRegisterMetaType<GstCaps*>("GstCaps*");
qRegisterMetaType<State>("State");
@@ -902,8 +903,13 @@ void MediaObject::setSource(const MediaSource &source)
break;
case MediaSource::Disc: // CD tracks can be specified by setting the url in the following way uri=cdda:4
- m_backend->logMessage("Source type Disc not currently supported", Backend::Warning, this);
- setError(tr("Could not open media source."), Phonon::NormalError);
+ {
+ QUrl cdurl(QLatin1String("cdda://"));
+ if (createPipefromURL(cdurl))
+ m_loading = true;
+ else
+ setError(tr("Could not open media source."));
+ }
break;
default:
@@ -954,6 +960,19 @@ void MediaObject::getStreamInfo()
m_hasVideo = m_videoStreamFound;
emit hasVideoChanged(m_hasVideo);
}
+
+ m_availableTitles = 1;
+ gint64 titleCount;
+ GstFormat format = gst_format_get_by_nick("track");
+ if (gst_element_query_duration (m_pipeline, &format, &titleCount)) {
+ int oldAvailableTitles = m_availableTitles;
+ m_availableTitles = (int)titleCount;
+ if (m_availableTitles != oldAvailableTitles) {
+ emit availableTitlesChanged(m_availableTitles);
+ m_backend->logMessage(QString("Available titles changed: %0").arg(m_availableTitles), Backend::Info, this);
+ }
+ }
+
}
void MediaObject::setPrefinishMark(qint32 newPrefinishMark)
@@ -1351,6 +1370,13 @@ void MediaObject::handleEndOfStream()
if (!m_seekable)
m_atEndOfStream = true;
+ if (m_autoplayTitles &&
+ m_availableTitles > 1 &&
+ m_currentTitle < m_availableTitles) {
+ _iface_setCurrentTitle(m_currentTitle + 1);
+ return;
+ }
+
if (m_nextSource.type() != MediaSource::Invalid
&& m_nextSource.type() != MediaSource::Empty) { // We only emit finish when the queue is actually empty
QTimer::singleShot (qMax(0, transitionTime()), this, SLOT(beginPlay()));
@@ -1379,6 +1405,72 @@ void MediaObject::notifyStateChange(Phonon::State newstate, Phonon::State oldsta
notify(&event);
}
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+//interface management
+bool MediaObject::hasInterface(Interface iface) const
+{
+ return iface == AddonInterface::TitleInterface;
+}
+
+QVariant MediaObject::interfaceCall(Interface iface, int command, const QList<QVariant> &params)
+{
+ if (hasInterface(iface)) {
+
+ switch (iface)
+ {
+ case TitleInterface:
+ switch (command)
+ {
+ case availableTitles:
+ return _iface_availableTitles();
+ case title:
+ return _iface_currentTitle();
+ case setTitle:
+ _iface_setCurrentTitle(params.first().toInt());
+ break;
+ case autoplayTitles:
+ return m_autoplayTitles;
+ case setAutoplayTitles:
+ m_autoplayTitles = params.first().toBool();
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return QVariant();
+}
+#endif
+
+int MediaObject::_iface_availableTitles() const
+{
+ return m_availableTitles;
+}
+
+int MediaObject::_iface_currentTitle() const
+{
+ return m_currentTitle;
+}
+
+void MediaObject::_iface_setCurrentTitle(int title)
+{
+ GstFormat trackFormat = gst_format_get_by_nick("track");
+ m_backend->logMessage(QString("setCurrentTitle %0").arg(title), Backend::Info, this);
+ if ((title == m_currentTitle) || (title < 1) || (title > m_availableTitles))
+ return;
+
+ m_currentTitle = title;
+
+ //let's seek to the beginning of the song
+ if (gst_element_seek_simple(m_pipeline, trackFormat, GST_SEEK_FLAG_FLUSH, m_currentTitle - 1)) {
+ updateTotalTime();
+ m_atEndOfStream = false;
+ emit titleChanged(title);
+ emit totalTimeChanged(totalTime());
+ }
+}
+
} // ns Gstreamer
} // ns Phonon
diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.h b/src/3rdparty/phonon/gstreamer/mediaobject.h
index 4dc3f12..64b3510 100644
--- a/src/3rdparty/phonon/gstreamer/mediaobject.h
+++ b/src/3rdparty/phonon/gstreamer/mediaobject.h
@@ -21,7 +21,6 @@
#include "backend.h"
#include "common.h"
#include "medianode.h"
-
#include <phonon/mediaobjectinterface.h>
#include <phonon/addoninterface.h>
@@ -32,7 +31,6 @@
#include <QtCore/QDate>
#include <QtCore/QEvent>
#include <QtCore/QUrl>
-
#include <gst/gst.h>
QT_BEGIN_NAMESPACE
@@ -50,11 +48,20 @@ class AudioPath;
class VideoPath;
class AudioOutput;
-class MediaObject : public QObject, public MediaObjectInterface, public AddonInterface, public MediaNode
+class MediaObject : public QObject, public MediaObjectInterface
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+ , public AddonInterface
+#endif
+ , public MediaNode
{
friend class Stream;
Q_OBJECT
- Q_INTERFACES(Phonon::MediaObjectInterface Phonon::AddonInterface Phonon::Gstreamer::MediaNode)
+ Q_INTERFACES(Phonon::MediaObjectInterface
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+ Phonon::AddonInterface
+#endif
+ Phonon::Gstreamer::MediaNode
+ )
public:
@@ -93,16 +100,10 @@ public:
MediaSource source() const;
// No additional interfaces currently supported
- bool hasInterface(Interface) const
- {
- return false;
- }
-
- QVariant interfaceCall(Interface, int, const QList<QVariant> &)
- {
- return QVariant();
- }
-
+#ifndef QT_NO_PHONON_MEDIACONTROLLER
+ bool hasInterface(Interface) const;
+ QVariant interfaceCall(Interface, int, const QList<QVariant> &);
+#endif
bool isLoading()
{
return m_loading;
@@ -176,6 +177,19 @@ Q_SIGNALS:
QMultiMap<QString, QString> metaData();
void setMetaData(QMultiMap<QString, QString> newData);
+ // AddonInterface:
+ void titleChanged(int);
+ void availableTitlesChanged(int);
+
+ // Not implemented
+ void chapterChanged(int);
+ void availableChaptersChanged(int);
+ void angleChanged(int);
+ void availableAnglesChanged(int);
+
+ void availableSubtitlesChanged();
+ void availableAudioChannelsChanged();
+
protected:
void beginLoad();
void loadingComplete();
@@ -219,6 +233,10 @@ private:
void updateSeekable();
qint64 getPipelinePos() const;
+ int _iface_availableTitles() const;
+ int _iface_currentTitle() const;
+ void _iface_setCurrentTitle(int title);
+
bool m_resumeState;
State m_oldState;
quint64 m_oldPos;
@@ -264,6 +282,9 @@ private:
bool m_resetNeeded;
QStringList m_missingCodecs;
QMultiMap<QString, QString> m_metaData;
+ bool m_autoplayTitles;
+ int m_availableTitles;
+ int m_currentTitle;
};
}
} //namespace Phonon::Gstreamer
diff --git a/src/3rdparty/phonon/gstreamer/x11renderer.cpp b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
index 1de58b6..73877a8 100644
--- a/src/3rdparty/phonon/gstreamer/x11renderer.cpp
+++ b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
@@ -137,6 +137,7 @@ void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
void X11Renderer::movieSizeChanged(const QSize &movieSize)
{
+ Q_UNUSED(movieSize);
if (m_renderWidget) {
m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
}
diff --git a/src/3rdparty/phonon/qt7/audionode.mm b/src/3rdparty/phonon/qt7/audionode.mm
index cb9e82f..961230c 100644
--- a/src/3rdparty/phonon/qt7/audionode.mm
+++ b/src/3rdparty/phonon/qt7/audionode.mm
@@ -68,13 +68,15 @@ void AudioNode::createAndConnectAUNodes()
<< QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!"))
OSStatus err = noErr;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
- err = AUGraphAddNode(m_audioGraph->audioGraphRef(), &description, &m_auNode);
- else
-#endif
- err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode);
-
+
+ // The proper function to call here is AUGraphAddNode() but the type has
+ // changed between 10.5 and 10.6. it's still OK to call this function, but
+ // if we want to use the proper thing we need to move over to
+ // AudioComponentDescription everywhere, which is very similar to the
+ // ComponentDescription, but a different size. however,
+ // AudioComponentDescription only exists on 10.6+. More fun than we need to
+ // deal with at the moment, so we'll take the "deprecated" warning instead.
+ err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode);
BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR)
BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR)
}
diff --git a/src/3rdparty/phonon/qt7/backendinfo.mm b/src/3rdparty/phonon/qt7/backendinfo.mm
index e173f05..0d51db0 100644
--- a/src/3rdparty/phonon/qt7/backendinfo.mm
+++ b/src/3rdparty/phonon/qt7/backendinfo.mm
@@ -22,6 +22,7 @@
#include <AudioUnit/AudioUnit.h>
#include <CoreServices/CoreServices.h>
+#include <QtGui/qmacdefines_mac.h>
#import <QTKit/QTMovie.h>
#ifdef QUICKTIME_C_API_AVAILABLE
diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
index 0b3aec2..b80570a 100644
--- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
+++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h
@@ -20,6 +20,7 @@
#include "backendheader.h"
+#include <QtGui/qmacdefines_mac.h>
#import <QTKit/QTDataReference.h>
#import <QTKit/QTMovie.h>
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index 5bb8a51..bfaefa2 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
- 0ba3dbe8c83850cd3c3874e3dca95b35b45fd86e
+ 450331808bfe11b1472c213a8cb311190355c2de
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index 2e2ce52..9be6e72 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,159 @@
+2009-02-04 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Unreviewed Qt build fix.
+
+ Changed ASSERT(image) to ASSERT(!image.isNull()).
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-02-03 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData()
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-02-03 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Sam Weinig and Oliver Hunt.
+
+ Added getImageData() support for QtWebKit.
+
+ [QT] lacks getImageData / putImageData support in Canvas
+ https://bugs.webkit.org/show_bug.cgi?id=22186
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-04-14 Benjamin C Meyer <benjamin.meyer@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=25099
+
+ When creating a QNetworkRequest make sure to populate the
+ CacheLoadControlAttribute with the value set by the ResourceRequest::cachePolicy() so that the cache will be used as WebKit expects.
+
+ * WebKit/qt/tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::requestCache):
+
+ * platform/network/qt/ResourceRequestQt.cpp:
+ (WebCore::ResourceRequest::toNetworkRequest):
+
+2009-04-07 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ While working on <rdar://problem/5968249>, noticed some glaring problems with LocalStorage.
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::localStorage): Return the cached m_localStorage object if it exists to
+ avoid creating multiple representations for the same underlying StorageArea.
+ * page/DOMWindow.h:
+ (WebCore::DOMWindow::optionalLocalStorage): Return m_localStorage, not m_sessionStorage.
+
+2009-04-06 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Don't show and hide the platformPluginWidget, as it's our QWebView
+
+ * plugins/mac/PluginViewMac.cpp:
+ (WebCore::PluginView::show):
+ (WebCore::PluginView::hide):
+ (WebCore::PluginView::setParentVisible):
+
+2009-04-06 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Eric Seidel.
+
+ HTMLCanvasElement crash when ImageBuffer creation fails.
+ https://bugs.webkit.org/show_bug.cgi?id=23212
+
+ Check for NULL before using the ImageBuffer as we might
+ be low on memory and creation may have failed.
+
+ Test case creation blocked by:
+ https://bugs.webkit.org/show_bug.cgi?id=25055
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::createImageBuffer):
+
+2009-04-05 Erik L. Bunce <elbunce@xendom.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=25050
+
+ Fix an assert failure when dropping an 'empty' text/uri-list on a QWebView.
+
+ * platform/qt/DragDataQt.cpp:
+ (WebCore::DragData::asURL):
+
+2009-03-27 Zack Rusin <zack@kde.org>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24280
+
+ Fix propagation of fill rules when rendering paths in the Qt build.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::toQtFillRule):
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+
+2009-03-27 Zack Rusin <zack@kde.org>
+
+ Reviewed by Tor Arne Vestbø.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24275
+
+ Fix text field theming in the Qt build with the KDE 4 Oxygen
+ style by adjusting the size vertically and horizontally to
+ set padding on the element equal to the width of the style painted border.
+
+ * platform/qt/RenderThemeQt.cpp:
+ (WebCore::RenderThemeQt::RenderThemeQt):
+ (WebCore::RenderThemeQt::computeSizeBasedOnStyle):
+ (WebCore::RenderThemeQt::adjustTextFieldStyle):
+ (WebCore::RenderThemeQt::paintTextField):
+ * platform/qt/RenderThemeQt.h:
+
+2009-02-06 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ Fix bug in clearRect(). Use fillRect() instead of eraseRect() to get
+ the context transparent.
+
+ [QT] clearRect fill's a given rect with white
+ https://bugs.webkit.org/show_bug.cgi?id=23728
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::clearRect):
+
+2009-03-19 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fixed support for doing calls from JavaScript into NPAPI Plugins for the Qt port on Windows.
+
+ Removed dead code for distinguishing between Widget and PluginView in the Qt port.
+
+ * bindings/js/ScriptControllerQt.cpp:
+ (WebCore::ScriptController::createScriptInstanceForWidget): Removed incorrect isNPAPI check.
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::PluginView): Removed m_isNPAPIPlugin variable.
+ * plugins/PluginView.h: Removed setter/getter.
+ * plugins/mac/PluginViewMac.cpp:
+ (WebCore::PluginView::init): Removed call to setIsNPAPIPlugin.
+ * plugins/qt/PluginViewQt.cpp:
+ (WebCore::PluginView::init): Ditto.
+
2009-02-26 Benjamin Meyer <benjamin.meyer@torchmobile.com>
Reviewed by George Staikos.
diff --git a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp
index 15593fc..6b14190 100644
--- a/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp
+++ b/src/3rdparty/webkit/WebCore/bindings/js/ScriptControllerQt.cpp
@@ -50,9 +50,7 @@ PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWid
{
if (widget->isPluginView()) {
PluginView* pluginView = static_cast<PluginView*>(widget);
- if (pluginView->isNPAPIPlugin())
- return pluginView->bindingInstance();
- return 0;
+ return pluginView->bindingInstance();
}
QWidget* platformWidget = widget->platformWidget();
diff --git a/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp
index fb6d9fe..76c3202 100644
--- a/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp
+++ b/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp
@@ -257,6 +257,10 @@ void HTMLCanvasElement::createImageBuffer() const
return;
m_imageBuffer.set(ImageBuffer::create(size, false).release());
+ // The convertLogicalToDevice MaxCanvasArea check should prevent common cases
+ // where ImageBuffer::create() returns NULL, however we could still be low on memory.
+ if (!m_imageBuffer)
+ return;
m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()));
m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
}
diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
index 42d2e90..dd14fb9 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
+++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
@@ -333,6 +333,9 @@ Storage* DOMWindow::sessionStorage() const
Storage* DOMWindow::localStorage() const
{
+ if (m_localStorage)
+ return m_localStorage.get();
+
Document* document = this->document();
if (!document)
return 0;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h
index 0277441..e7fab18 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h
+++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h
@@ -265,7 +265,7 @@ namespace WebCore {
Location* optionalLocation() const { return m_location.get(); }
#if ENABLE(DOM_STORAGE)
Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
- Storage* optionalLocalStorage() const { return m_sessionStorage.get(); }
+ Storage* optionalLocalStorage() const { return m_localStorage.get(); }
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 80a6390..936c1ea 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -168,6 +168,18 @@ static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMeth
return gradient;
}
+static inline Qt::FillRule toQtFillRule(WindRule rule)
+{
+ switch(rule) {
+ case RULE_EVENODD:
+ return Qt::OddEvenFill;
+ case RULE_NONZERO:
+ return Qt::WindingFill;
+ }
+ qDebug("Qt: unrecognized wind rule!");
+ return Qt::OddEvenFill;
+}
+
struct TransparencyLayer
{
TransparencyLayer(const QPainter* p, const QRect &rect)
@@ -541,6 +553,7 @@ void GraphicsContext::fillPath()
QPainter *p = m_data->p();
QPainterPath path = m_data->currentPath;
+ path.setFillRule(toQtFillRule(fillRule()));
switch (m_common->state.fillColorSpace) {
case SolidColorSpace:
@@ -569,6 +582,7 @@ void GraphicsContext::strokePath()
QPainter *p = m_data->p();
QPen pen = p->pen();
QPainterPath path = m_data->currentPath;
+ path.setFillRule(toQtFillRule(fillRule()));
switch (m_common->state.strokeColorSpace) {
case SolidColorSpace:
@@ -815,7 +829,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
QPainter::CompositionMode currentCompositionMode = p->compositionMode();
if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
p->setCompositionMode(QPainter::CompositionMode_Source);
- p->eraseRect(rect);
+ p->fillRect(rect, Qt::transparent);
if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
p->setCompositionMode(currentCompositionMode);
}
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index d4ab59f..d1009b5 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -35,6 +35,8 @@
#include "StillImageQt.h"
#include <QBuffer>
+#include <QColor>
+#include <QImage>
#include <QImageWriter>
#include <QPainter>
#include <QPixmap>
@@ -79,10 +81,57 @@ Image* ImageBuffer::image() const
return m_image.get();
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
{
- notImplemented();
- return 0;
+ PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
+ unsigned char* data = result->data()->data();
+
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
+ memset(data, 0, result->data()->length());
+
+ int originx = rect.x();
+ int destx = 0;
+ if (originx < 0) {
+ destx = -originx;
+ originx = 0;
+ }
+ int endx = rect.x() + rect.width();
+ if (endx > m_size.width())
+ endx = m_size.width();
+ int numColumns = endx - originx;
+
+ int originy = rect.y();
+ int desty = 0;
+ if (originy < 0) {
+ desty = -originy;
+ originy = 0;
+ }
+ int endy = rect.y() + rect.height();
+ if (endy > m_size.height())
+ endy = m_size.height();
+ int numRows = endy - originy;
+
+ QImage image = m_data.m_pixmap.toImage();
+ if (image.format() != QImage::Format_ARGB32)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+ ASSERT(!image.isNull());
+
+ unsigned destBytesPerRow = 4 * rect.width();
+ unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
+ for (int y = 0; y < numRows; ++y) {
+ for (int x = 0; x < numColumns; x++) {
+ QRgb value = image.pixel(x + originx, y + originy);
+ int basex = x * 4;
+
+ destRows[basex] = qRed(value);
+ destRows[basex + 1] = qGreen(value);
+ destRows[basex + 2] = qBlue(value);
+ destRows[basex + 3] = qAlpha(value);
+ }
+ destRows += destBytesPerRow;
+ }
+
+ return result;
}
void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&)
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp
index 9308878..c8f6ad5 100644
--- a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -41,6 +41,22 @@ QNetworkRequest ResourceRequest::toNetworkRequest() const
request.setRawHeader(name, value);
}
+ switch (cachePolicy()) {
+ case ReloadIgnoringCacheData:
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
+ break;
+ case ReturnCacheDataElseLoad:
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+ break;
+ case ReturnCacheDataDontLoad:
+ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
+ break;
+ case UseProtocolCachePolicy:
+ // QNetworkRequest::PreferNetwork
+ default:
+ break;
+ }
+
return request;
}
diff --git a/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp
index 9d95373..218f7be 100644
--- a/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -126,6 +126,10 @@ String DragData::asURL(String* title) const
if (!m_platformDragData)
return String();
QList<QUrl> urls = m_platformDragData->urls();
+
+ if (urls.isEmpty())
+ return String();
+
return urls.first().toString();
}
diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp
index cc9d314..a9da76b 100644
--- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp
@@ -41,6 +41,7 @@
#include <QWidget>
#include <QPainter>
#include <QPushButton>
+#include <QLineEdit>
#include <QStyleFactory>
#include <QStyleOptionButton>
#include <QStyleOptionFrameV2>
@@ -123,6 +124,12 @@ RenderThemeQt::RenderThemeQt()
#endif
m_fallbackStyle = 0;
+
+ // this will need to be regenerated when the style changes
+ QLineEdit lineEdit;
+ QStyleOptionFrameV2 opt;
+ m_frameLineWidth = QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth,
+ &opt, &lineEdit);
}
RenderThemeQt::~RenderThemeQt()
@@ -268,7 +275,7 @@ int RenderThemeQt::minimumMenuListSize(RenderStyle*) const
return 7 * fm.width(QLatin1Char('x'));
}
-static void computeSizeBasedOnStyle(RenderStyle* renderStyle)
+void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
{
// If the width and height are both specified, then we have nothing to do.
if (!renderStyle->width().isIntrinsicOrAuto() && !renderStyle->height().isAuto())
@@ -335,13 +342,15 @@ static void computeSizeBasedOnStyle(RenderStyle* renderStyle)
int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin;
int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin;
QStyleOptionFrameV2 opt;
- opt.lineWidth = applicationStyle->pixelMetric(QStyle::PM_DefaultFrameWidth,
- &opt, 0);
+ opt.lineWidth = m_frameLineWidth;
QSize sz = applicationStyle->sizeFromContents(QStyle::CT_LineEdit,
- &opt,
- QSize(w, h).expandedTo(QApplication::globalStrut()),
- 0);
+ &opt,
+ QSize(w, h).expandedTo(QApplication::globalStrut()),
+ 0);
size.setHeight(sz.height());
+
+ renderStyle->setPaddingLeft(Length(opt.lineWidth, Fixed));
+ renderStyle->setPaddingRight(Length(opt.lineWidth, Fixed));
break;
}
default:
@@ -482,6 +491,9 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style,
{
style->setBackgroundColor(Color::transparent);
style->setColor(QApplication::palette().text().color());
+ style->resetBorder();
+ style->resetPadding();
+ computeSizeBasedOnStyle(style);
}
bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
@@ -495,7 +507,7 @@ bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInf
panel.initFrom(p.widget);
panel.rect = r;
- panel.lineWidth = p.style->pixelMetric(QStyle::PM_DefaultFrameWidth, &panel, p.widget);
+ panel.lineWidth = m_frameLineWidth;
panel.state |= QStyle::State_Sunken;
panel.features = QStyleOptionFrameV2::None;
diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h
index b4a5064..5c78a72 100644
--- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h
+++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h
@@ -128,6 +128,7 @@ private:
void paintMediaBackground(QPainter* painter, const IntRect& r) const;
QColor getMediaControlForegroundColor(RenderObject* o = 0) const;
#endif
+ void computeSizeBasedOnStyle(RenderStyle* renderStyle) const;
private:
bool supportsFocus(ControlPart) const;
@@ -144,6 +145,8 @@ private:
QStyle* m_fallbackStyle;
QStyle* fallbackStyle();
+
+ int m_frameLineWidth;
};
class StylePainter
diff --git a/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp b/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp
index dbc090f..61d3157 100644
--- a/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/PluginView.cpp
@@ -559,9 +559,6 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p
#if PLATFORM(GTK) || defined(Q_WS_X11)
, m_needsXEmbed(false)
#endif
-#if PLATFORM(QT)
- , m_isNPAPIPlugin(false)
-#endif
#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
, m_pluginWndProc(0)
, m_lastMessage(0)
diff --git a/src/3rdparty/webkit/WebCore/plugins/PluginView.h b/src/3rdparty/webkit/WebCore/plugins/PluginView.h
index 0fe352f..44f2146 100644
--- a/src/3rdparty/webkit/WebCore/plugins/PluginView.h
+++ b/src/3rdparty/webkit/WebCore/plugins/PluginView.h
@@ -187,11 +187,6 @@ namespace WebCore {
static bool isCallingPlugin();
-#if PLATFORM(QT)
- bool isNPAPIPlugin() const { return m_isNPAPIPlugin; }
- void setIsNPAPIPlugin(bool b) { m_isNPAPIPlugin = b; }
-#endif
-
private:
PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
@@ -257,10 +252,6 @@ namespace WebCore {
bool m_isTransparent;
bool m_haveInitialized;
-#if PLATFORM(QT)
- bool m_isNPAPIPlugin;
-#endif
-
#if PLATFORM(GTK) || defined(Q_WS_X11)
bool m_needsXEmbed;
#endif
diff --git a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp
index c95e854..1d7d570 100644
--- a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp
@@ -158,8 +158,6 @@ void PluginView::init()
m_npWindow.clipRect.right = 0;
m_npWindow.clipRect.bottom = 0;
- setIsNPAPIPlugin(true);
-
show();
m_status = PluginStatusLoadedSuccessfully;
@@ -301,9 +299,6 @@ void PluginView::show()
setSelfVisible(true);
- if (isParentVisible() && platformPluginWidget())
- platformPluginWidget()->setVisible(true);
-
Widget::show();
}
@@ -313,9 +308,6 @@ void PluginView::hide()
setSelfVisible(false);
- if (isParentVisible() && platformPluginWidget())
- platformPluginWidget()->setVisible(false);
-
Widget::hide();
}
@@ -347,9 +339,6 @@ void PluginView::setParentVisible(bool visible)
return;
Widget::setParentVisible(visible);
-
- if (isSelfVisible() && platformPluginWidget())
- platformPluginWidget()->setVisible(visible);
}
void PluginView::setNPWindowRect(const IntRect&)
diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp
index 4982d08..5aa8933 100644
--- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp
@@ -459,7 +459,6 @@ void PluginView::init()
if (m_needsXEmbed) {
setPlatformWidget(new QX11EmbedContainer(m_parentFrame->view()->hostWindow()->platformWindow()));
- setIsNPAPIPlugin(true);
} else {
notImplemented();
m_status = PluginStatusCanNotLoadPlugin;
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h
index f4c368a..4e832bb 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h
@@ -26,7 +26,7 @@
namespace WebCore {
class DatabaseDetails;
-};
+}
class QWebDatabasePrivate;
class QWebSecurityOrigin;
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
index ae71356..5dc6363 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
@@ -534,6 +534,8 @@ void QWebFrame::load(const QNetworkRequest &req,
Sets the content of this frame to \a html. \a baseUrl is optional and used to resolve relative
URLs in the document, such as referenced images or stylesheets.
+ The \a html is loaded immediately; external objects are loaded asynchronously.
+
When using this method WebKit assumes that external resources such as JavaScript programs or style
sheets are encoded in UTF-8 unless otherwise specified. For example, the encoding of an external
script can be specified through the charset attribute of the HTML script tag. It is also possible
@@ -558,6 +560,8 @@ void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
External objects referenced in the content are located relative to \a baseUrl.
+ The \a data is loaded immediately; external objects are loaded asynchronously.
+
\sa toHtml()
*/
void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index 0e5b5da..e17306d 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -451,60 +451,35 @@ void QWebPagePrivate::updateAction(QWebPage::WebAction action)
case QWebPage::Reload:
enabled = !loader->isLoading();
break;
- case QWebPage::Cut:
- enabled = editor->canCut();
- break;
- case QWebPage::Copy:
- enabled = editor->canCopy();
- break;
- case QWebPage::Paste:
- enabled = editor->canPaste();
- break;
#ifndef QT_NO_UNDOSTACK
case QWebPage::Undo:
case QWebPage::Redo:
// those two are handled by QUndoStack
break;
#endif // QT_NO_UNDOSTACK
- case QWebPage::MoveToNextChar:
- case QWebPage::MoveToPreviousChar:
- case QWebPage::MoveToNextWord:
- case QWebPage::MoveToPreviousWord:
- case QWebPage::MoveToNextLine:
- case QWebPage::MoveToPreviousLine:
- case QWebPage::MoveToStartOfLine:
- case QWebPage::MoveToEndOfLine:
- case QWebPage::MoveToStartOfBlock:
- case QWebPage::MoveToEndOfBlock:
- case QWebPage::MoveToStartOfDocument:
- case QWebPage::MoveToEndOfDocument:
- case QWebPage::SelectNextChar:
- case QWebPage::SelectPreviousChar:
- case QWebPage::SelectNextWord:
- case QWebPage::SelectPreviousWord:
- case QWebPage::SelectNextLine:
- case QWebPage::SelectPreviousLine:
- case QWebPage::SelectStartOfLine:
- case QWebPage::SelectEndOfLine:
- case QWebPage::SelectStartOfBlock:
- case QWebPage::SelectEndOfBlock:
- case QWebPage::SelectStartOfDocument:
- case QWebPage::SelectEndOfDocument:
- case QWebPage::DeleteStartOfWord:
- case QWebPage::DeleteEndOfWord:
+ case QWebPage::SelectAll: // editor command is always enabled
+ break;
case QWebPage::SetTextDirectionDefault:
case QWebPage::SetTextDirectionLeftToRight:
case QWebPage::SetTextDirectionRightToLeft:
- case QWebPage::ToggleBold:
- case QWebPage::ToggleItalic:
- case QWebPage::ToggleUnderline:
- enabled = editor->canEditRichly();
- if (enabled)
- checked = editor->command(editorCommandForWebActions(action)).state() != FalseTriState;
- else
- checked = false;
+ enabled = editor->canEdit();
+ checked = false;
+ break;
+ default: {
+ // see if it's an editor command
+ const char* commandName = editorCommandForWebActions(action);
+
+ // if it's an editor command, let it's logic determine state
+ if (commandName) {
+ Editor::Command command = editor->command(commandName);
+ enabled = command.isEnabled();
+ if (enabled)
+ checked = command.state() != FalseTriState;
+ else
+ checked = false;
+ }
break;
- default: break;
+ }
}
a->setEnabled(enabled);
@@ -558,6 +533,8 @@ void QWebPagePrivate::updateEditorActions()
updateAction(QWebPage::ToggleBold);
updateAction(QWebPage::ToggleItalic);
updateAction(QWebPage::ToggleUnderline);
+ updateAction(QWebPage::InsertParagraphSeparator);
+ updateAction(QWebPage::InsertLineSeparator);
}
void QWebPagePrivate::timerEvent(QTimerEvent *ev)
@@ -919,14 +896,14 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
return;
}
- if (!ev->preeditString().isEmpty()) {
+ if (!ev->commitString().isEmpty())
+ editor->confirmComposition(ev->commitString());
+ else {
QString preedit = ev->preeditString();
// ### FIXME: use the provided QTextCharFormat (use color at least)
Vector<CompositionUnderline> underlines;
underlines.append(CompositionUnderline(0, preedit.length(), Color(0,0,0), false));
editor->setComposition(preedit, underlines, preedit.length(), 0);
- } else if (!ev->commitString().isEmpty()) {
- editor->confirmComposition(ev->commitString());
}
ev->accept();
}
@@ -1116,8 +1093,13 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
\enum QWebPage::WebAction
This enum describes the types of action which can be performed on the web page.
- Actions which are related to text editing, cursor movement, and text selection
- only have an effect if \l contentEditable is true.
+
+ Actions only have an effect when they are applicable. The availability of
+ actions can be be determined by checking \l{QAction::}{enabled()} on the
+ action returned by \l{QWebPage::}{action()}.
+
+ One method of enabling the text editing, cursor movement, and text selection actions
+ is by setting \l contentEditable to true.
\value NoWebAction No action is triggered.
\value OpenLink Open the current link.
@@ -1737,6 +1719,9 @@ QAction *QWebPage::action(WebAction action) const
case MoveToEndOfDocument:
text = tr("Move the cursor to the end of the document");
break;
+ case SelectAll:
+ text = tr("Select all");
+ break;
case SelectNextChar:
text = tr("Select to the next character");
break;
@@ -1809,6 +1794,13 @@ QAction *QWebPage::action(WebAction action) const
text = contextMenuItemTagInspectElement();
break;
+ case InsertParagraphSeparator:
+ text = tr("Insert a new paragraph");
+ break;
+ case InsertLineSeparator:
+ text = tr("Insert a new line");
+ break;
+
case NoWebAction:
return 0;
}
@@ -2336,7 +2328,8 @@ QWebPluginFactory *QWebPage::pluginFactory() const
\list
\o %Platform% and %Subplatform% are expanded to the windowing system and the operation system.
\o %Security% expands to U if SSL is enabled, otherwise N. SSL is enabled if QSslSocket::supportsSsl() returns true.
- \o %Locale% is replaced with QLocale::name().
+ \o %Locale% is replaced with QLocale::name(). The locale is determined from the view of the QWebPage. If no view is set on the QWebPage,
+ then a default constructed QLocale is used instead.
\o %WebKitVersion% currently expands to 527+
\o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
\endlist
@@ -2524,7 +2517,7 @@ void QWebPagePrivate::_q_onLoadProgressChanged(int) {
\sa bytesReceived()
*/
quint64 QWebPage::totalBytes() const {
- return d->m_bytesReceived;
+ return d->m_totalBytes;
}
@@ -2534,7 +2527,7 @@ quint64 QWebPage::totalBytes() const {
\sa totalBytes()
*/
quint64 QWebPage::bytesReceived() const {
- return d->m_totalBytes;
+ return d->m_bytesReceived;
}
/*!
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.h
index ebe4a77..b52194d 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.h
@@ -28,7 +28,7 @@
namespace WebCore {
class SecurityOrigin;
class ChromeClientQt;
-};
+}
class QWebSecurityOriginPrivate;
class QWebDatabase;
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp
index ea503a1..a843eba 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp
@@ -289,6 +289,8 @@ void QWebView::load(const QNetworkRequest &request,
External objects such as stylesheets or images referenced in the HTML
document are located relative to \a baseUrl.
+ The \a html is loaded immediately; external objects are loaded asynchronously.
+
When using this method, WebKit assumes that external resources such as
JavaScript programs or style sheets are encoded in UTF-8 unless otherwise
specified. For example, the encoding of an external script can be specified
@@ -309,6 +311,8 @@ void QWebView::setHtml(const QString &html, const QUrl &baseUrl)
External objects referenced in the content are located relative to \a baseUrl.
+ The \a data is loaded immediately; external objects are loaded asynchronously.
+
\sa load(), setHtml(), QWebFrame::toHtml()
*/
void QWebView::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 8e0b50a..5a23200 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,122 @@
+2009-03-07 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Cameron Zwarich.
+
+ These methods are clearly returning the wrong values as the two were
+ returning swapped information.
+
+ * Api/qwebpage.cpp:
+ (QWebPage::totalBytes):
+ (QWebPage::bytesReceived):
+
+2009-04-02 Takumi Asaki <takumi.asaki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix pre-edit handling of text fields with input methods.
+
+ The input method sends an empty preeditString() if all characters of
+ the preedit should be deleted. So inputMethodEvent() has to use
+ preeditString() if it's empty.
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::inputMethodEvent):
+
+2009-03-30 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ Document that setHtml/setContent loads only the html/data immediately, not external objects.
+
+ * Api/qwebframe.cpp:
+ * Api/qwebview.cpp:
+
+2009-03-26 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ Fix the documentation of the QLocale usage in userAgentForUrl.
+
+ * Api/qwebpage.cpp:
+
+2009-03-20 Erik L. Bunce <elbunce@xendom.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix for InsertParagraphSeparator and InsertLineSeparator so that
+ QWebPage::action() creates QActions for them. Also make sure they get
+ updated appropriately.
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::updateEditorActions):
+ (QWebPage::action):
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::textEditing):
+
+2009-03-20 Erik L. Bunce <elbunce@xendom.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fix QWebPage::WebActions action states to more closely match when they are
+ actually applicable and remove erroneous documentation.
+
+ * Most WebActions implemented using editor commands now use the
+ Editor::Command::isEnabled() to control their availability.
+ * SelectAll is always enabled (since it's editor command is).
+ * SetTextDirection{} family of WebActions are available when canEdit() is true
+ and not just canEditRichly().
+
+ Fix and clarify documentation about the availability of various web actions.
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::updateAction):
+ (QWebPagePrivate::updateEditorActions):
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::textSelection):
+
+2009-03-19 Ariya Hidayat <ariya.hidayat@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fixes pedantic compilation in QtWebKit.
+
+ There are no semi-colons after namespace declarations.
+
+ * Api/qwebdatabase.h:
+ * Api/qwebsecurityorigin.h:
+
+2009-03-19 David Boddie <dboddie@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Doc: Removed obsolete warning about Flash and other plugins.
+
+ * Api/qwebsettings.cpp:
+
+2009-03-19 Paul Olav Tvete <paul.tvete@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Properly escape tooltip text
+
+ ManualTest: http://xkcd.com/554/
+
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::setToolTip):
+
+2009-03-03 Ariya Hidayat <ariya.hidayat@trolltech.com>
+
+ Rubber-stamped by Simon Hausmann.
+
+ [Qt] Create and update the action for SelectAll.
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::updateAction):
+ (QWebPagePrivate::updateEditorActions):
+ (QWebPage::action):
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::textSelection):
+
2009-02-25 Kavindra Palaraja <kavindra.palaraja@nokia.com>
Reviewed by Simon Hausmann.
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 6f2ce3b..fe74fac 100644
--- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -106,6 +106,8 @@ private slots:
void textSelection();
void textEditing();
+ void requestCache();
+
private:
@@ -879,6 +881,7 @@ void tst_QWebPage::textSelection()
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
// these actions must exist
+ QVERIFY(page->action(QWebPage::SelectAll) != 0);
QVERIFY(page->action(QWebPage::SelectNextChar) != 0);
QVERIFY(page->action(QWebPage::SelectPreviousChar) != 0);
QVERIFY(page->action(QWebPage::SelectNextWord) != 0);
@@ -906,10 +909,14 @@ void tst_QWebPage::textSelection()
QCOMPARE(page->action(QWebPage::SelectStartOfDocument)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectEndOfDocument)->isEnabled(), false);
+ // ..but SelectAll is awalys enabled
+ QCOMPARE(page->action(QWebPage::SelectAll)->isEnabled(), true);
+
// make it editable before navigating the cursor
page->setContentEditable(true);
// here the actions are enabled after contentEditable is true
+ QCOMPARE(page->action(QWebPage::SelectAll)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextWord)->isEnabled(), true);
@@ -951,6 +958,8 @@ void tst_QWebPage::textEditing()
QVERIFY(page->action(QWebPage::ToggleBold) != 0);
QVERIFY(page->action(QWebPage::ToggleItalic) != 0);
QVERIFY(page->action(QWebPage::ToggleUnderline) != 0);
+ QVERIFY(page->action(QWebPage::InsertParagraphSeparator) != 0);
+ QVERIFY(page->action(QWebPage::InsertLineSeparator) != 0);
// right now they are disabled because contentEditable is false
QCOMPARE(page->action(QWebPage::DeleteStartOfWord)->isEnabled(), false);
@@ -961,6 +970,8 @@ void tst_QWebPage::textEditing()
QCOMPARE(page->action(QWebPage::ToggleBold)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleItalic)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleUnderline)->isEnabled(), false);
+ QCOMPARE(page->action(QWebPage::InsertParagraphSeparator)->isEnabled(), false);
+ QCOMPARE(page->action(QWebPage::InsertLineSeparator)->isEnabled(), false);
// make it editable before navigating the cursor
page->setContentEditable(true);
@@ -974,10 +985,38 @@ void tst_QWebPage::textEditing()
QCOMPARE(page->action(QWebPage::ToggleBold)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleItalic)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleUnderline)->isEnabled(), true);
+ QCOMPARE(page->action(QWebPage::InsertParagraphSeparator)->isEnabled(), true);
+ QCOMPARE(page->action(QWebPage::InsertLineSeparator)->isEnabled(), true);
delete page;
}
+void tst_QWebPage::requestCache()
+{
+ TestPage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.mainFrame()->setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(page.navigations.count(), 1);
+
+ page.mainFrame()->setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me2</a>"));
+ QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(page.navigations.count(), 2);
+
+ page.triggerAction(QWebPage::Stop);
+ QVERIFY(page.history()->canGoBack());
+ page.triggerAction(QWebPage::Back);
+
+ QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_COMPARE(page.navigations.count(), 3);
+ QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
+ (int)QNetworkRequest::PreferNetwork);
+ QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
+ (int)QNetworkRequest::PreferNetwork);
+ QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
+ (int)QNetworkRequest::PreferCache);
+}
QTEST_MAIN(tst_QWebPage)
#include "tst_qwebpage.moc"
diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp
index b9d73a1..f3e1dff 100644
--- a/src/activeqt/control/qaxserverbase.cpp
+++ b/src/activeqt/control/qaxserverbase.cpp
@@ -4457,11 +4457,24 @@ bool QAxServerBase::eventFilter(QObject *o, QEvent *e)
case QEvent::Resize:
updateMask();
break;
- case QEvent::WindowBlocked:
+ case QEvent::WindowBlocked: {
if (!m_spInPlaceFrame)
break;
m_spInPlaceFrame->EnableModeless(FALSE);
+ MSG msg;
+ // Visual Basic 6.0 posts the message WM_USER+3078 from the EnableModeless().
+ // While handling this message, VB will disable all current top-levels. After
+ // this we have to re-enable the Qt modal widget to receive input events.
+ if (PeekMessage(&msg, 0, WM_USER+3078, WM_USER+3078, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ QWidget *modalWidget = QApplication::activeModalWidget();
+ if (modalWidget && modalWidget->isVisible() && modalWidget->isEnabled()
+ && !IsWindowEnabled(modalWidget->effectiveWinId()))
+ EnableWindow(modalWidget->effectiveWinId(), TRUE);
+ }
break;
+ }
case QEvent::WindowUnblocked:
if (!m_spInPlaceFrame)
break;
diff --git a/src/corelib/concurrent/qtconcurrentreducekernel.h b/src/corelib/concurrent/qtconcurrentreducekernel.h
index e863b63..2dad519 100644
--- a/src/corelib/concurrent/qtconcurrentreducekernel.h
+++ b/src/corelib/concurrent/qtconcurrentreducekernel.h
@@ -51,6 +51,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qmutex.h>
#include <QtCore/qthread.h>
+#include <QtCore/qthreadpool.h>
#include <QtCore/qvector.h>
QT_BEGIN_HEADER
@@ -107,7 +108,7 @@ class ReduceKernel
const ReduceOptions reduceOptions;
QMutex mutex;
- int progress, resultsMapSize;
+ int progress, resultsMapSize, threadCount;
ResultsMap resultsMap;
bool canReduce(int begin) const
@@ -140,7 +141,8 @@ class ReduceKernel
public:
ReduceKernel(ReduceOptions _reduceOptions)
- : reduceOptions(_reduceOptions), progress(0), resultsMapSize(0)
+ : reduceOptions(_reduceOptions), progress(0), resultsMapSize(0),
+ threadCount(QThreadPool::globalInstance()->maxThreadCount())
{ }
void runReduce(ReduceFunctor &reduce,
@@ -210,12 +212,12 @@ public:
inline bool shouldThrottle()
{
- return (resultsMapSize > (ReduceQueueThrottleLimit * QThread::idealThreadCount()));
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
}
inline bool shouldStartThread()
{
- return (resultsMapSize <= (ReduceQueueStartLimit * QThread::idealThreadCount()));
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
}
};
diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt
index c26c274..40ccb15 100644
--- a/src/corelib/global/qfeatures.txt
+++ b/src/corelib/global/qfeatures.txt
@@ -3,28 +3,28 @@
Feature: PROPERTIES
Description: Supports scripting Qt-based applications.
Section: Kernel
-Requires:
+Requires:
Name: Properties
SeeAlso: ???
Feature: TEXTHTMLPARSER
Description: Parser for HTML
Section: Kernel
-Requires:
+Requires:
Name: HtmlParser
SeeAlso: ???
Feature: TEXTODFWRITER
Description: Provides an ODF writer
Section: Kernel
-Requires: XMLSTREAMWRITER
+Requires: XMLSTREAMWRITER
Name: OdfWriter
SeeAlso: ???
Feature: CSSPARSER
Description: Parser for Style Sheets
Section: Kernel
-Requires:
+Requires:
Name: CssParser
SeeAlso: ???
@@ -52,21 +52,21 @@ SeeAlso: ???
Feature: SESSIONMANAGER
Description: Supports session management.
Section: Kernel
-Requires:
+Requires:
Name: Session Manager
SeeAlso: ???
Feature: SHORTCUT
Description: Supports keyboard accelerators and shortcuts.
Section: Kernel
-Requires:
+Requires:
Name: QShortcut
SeeAlso: ???
Feature: ACTION
Description: Supports widget actions.
Section: Kernel
-Requires:
+Requires:
Name: QAction
SeeAlso: ???
@@ -129,8 +129,8 @@ SeeAlso: ???
Feature: XMLSTREAM
Description: Provides a simple streaming API for XML.
Section: Kernel
-Requires:
-Name:
+Requires:
+Name:
SeeAlso: ???
Feature: XMLSTREAMREADER
@@ -159,14 +159,14 @@ SeeAlso: ???
Feature: QUUID_STRING
Description: Supports convertion between UUID and strings.
Section: Data structures
-Requires:
+Requires:
Name: Universally Unique Identifier Convertion
SeeAlso: ???
Feature: TEXTDATE
Description: Supports month and day names in dates.
Section: Data structures
-Requires:
+Requires:
Name: Text Date
SeeAlso: ???
@@ -210,7 +210,7 @@ SeeAlso: ???
Feature: SETTINGS
Description: Supports persistent application settings.
Section: File I/O
-Requires: TEXTSTREAM
+Requires: TEXTSTREAM
Name: QSettings
SeeAlso: ???
@@ -229,7 +229,7 @@ Name: QFileSystemModel
SeeAlso: ???
Feature: FILESYSTEMWATCHER
-Description: Provides an interface for monitoring files and directories
+Description: Provides an interface for monitoring files and directories
for modications.
Section: File I/O
Requires: THREAD
@@ -239,7 +239,7 @@ SeeAlso: ???
# Widgets
Feature: TREEWIDGET
-Description: Supports views using tree models.
+Description: Supports views using tree models.
Section: Widgets
Requires: TREEVIEW
Name: QTreeWidget
@@ -283,7 +283,7 @@ SeeAlso: ???
Feature: SPLASHSCREEN
Description: Supports splash screens that can be shown during application startup.
Section: Widgets
-Requires:
+Requires:
Name: Splash screen widget
SeeAlso: ???
@@ -295,7 +295,7 @@ Name: QSplitter
SeeAlso: ???
Feature: LCDNUMBER
-Description: Supports LCD-like digits.
+Description: Supports LCD-like digits.
Section: Widgets
Requires:
Name: QLCDNumber
@@ -381,7 +381,7 @@ SeeAlso: ???
Feature: BUTTONGROUP
Description: Supports organizing groups of button widgets.
Section: Widgets
-Requires: GROUPBOX
+Requires: GROUPBOX
Name: QButtonGroup
SeeAlso: ???
@@ -393,7 +393,7 @@ Name: QMainWindow
SeeAlso: ???
Feature: DOCKWIDGET
-Description: Supports docking widgets inside a QMainWindow or floated as
+Description: Supports docking widgets inside a QMainWindow or floated as
a top-level window on the desktop.
Section: Widgets
Requires: RUBBERBAND MAINWINDOW
@@ -401,7 +401,7 @@ Name: QDockwidget
SeeAlso: ???
Feature: WORKSPACE
-Description: Supports workspace windows, e.g. used in an MDI application.
+Description: Supports workspace windows, e.g. used in an MDI application.
Section: Widgets
Requires: SCROLLBAR RESIZEHANDLER MENU TOOLBUTTON MAINWINDOW TOOLBAR MENUBAR
Name: QWorkSpace
@@ -457,8 +457,8 @@ Name: QSlider
SeeAlso: ???
Feature: SCROLLBAR
-Description: Supports scrollbars allowing the user access parts of a
-document that is larger than the widget used to display it.
+Description: Supports scrollbars allowing the user access parts of a
+document that is larger than the widget used to display it.
Section: Widgets
Requires: SLIDER
Name: QScrollBar
@@ -500,7 +500,7 @@ Name: QTextEdit
SeeAlso: ???
Feature: SYNTAXHIGHLIGHTER
-Description: Supports custom syntax highlighting.
+Description: Supports custom syntax highlighting.
Section: Widgets
Requires: TEXTEDIT
Name: QSyntaxHighlighter
@@ -556,7 +556,7 @@ Name: QSizeGrip
SeeAlso: ???
Feature: CALENDARWIDGET
-Description: Provides a monthly based calendar widget allowing the user to select
+Description: Provides a monthly based calendar widget allowing the user to select
a date.
Section: Widgets
Requires: TABLEVIEW MENU TEXTDATE SPINBOX TOOLBUTTON
@@ -567,14 +567,14 @@ Feature: PRINTPREVIEWWIDGET
Description: Provides a widget for previewing page layouts for printer output.
a date.
Section: Widgets
-Requires: GRAPHICSVIEW PRINTER PICTURE
+Requires: GRAPHICSVIEW PRINTER
Name: QPrintPreviewWidget
SeeAlso: ???
# Dialogs
Feature: MESSAGEBOX
-Description: Supports message boxes displaying
+Description: Supports message boxes displaying
informative messages and simple questions.
Section: Dialogs
Requires:
@@ -589,7 +589,7 @@ Name: QColorDialog
SeeAlso: ???
Feature: FILEDIALOG
-Description: Supports a dialog widget for selecting files or directories.
+Description: Supports a dialog widget for selecting files or directories.
Section: Dialogs
Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET FILESYSTEMMODEL
Name: QFileDialog
@@ -654,7 +654,7 @@ SeeAlso: ???
# ItemViews
Feature: ITEMVIEWS
-Description: Supports the model/view architecture managing the relationship
+Description: Supports the model/view architecture managing the relationship
between data and the way it is presented to the user.
Section: ItemViews
Requires: RUBBERBAND SCROLLAREA
@@ -683,8 +683,8 @@ Name: QAbstractProxyModel
SeeAlso: ???
Feature: SORTFILTERPROXYMODEL
-Description: Supports sorting and filtering of data passed between
-another model and a view.
+Description: Supports sorting and filtering of data passed between
+another model and a view.
Section: ItemViews
Requires: PROXYMODEL
Name: QSortFilterProxyModel
@@ -705,9 +705,9 @@ Name: QListView
SeeAlso: ???
Feature: TABLEVIEW
-Description: Supports a default model/view implementation of a table view.
+Description: Supports a default model/view implementation of a table view.
Section: ItemViews
-Requires: ITEMVIEWS
+Requires: ITEMVIEWS
Name: QTableView
SeeAlso: ???
@@ -735,21 +735,21 @@ SeeAlso: ???
# Styles
Feature: STYLE_WINDOWS
-Description: Supports a Microsoft Windows-like look and feel.
+Description: Supports a Microsoft Windows-like look and feel.
Section: Styles
Requires:
Name: QWindowsStyle
SeeAlso: ???
Feature: STYLE_MOTIF
-Description: Supports a Motif look and feel.
+Description: Supports a Motif look and feel.
Section: Styles
Requires:
Name: QMotifStyle
SeeAlso: ???
Feature: STYLE_CDE
-Description: Supports a CDE look and feel.
+Description: Supports a CDE look and feel.
Section: Styles
Requires: STYLE_MOTIF
Name: QCDEStyle
@@ -798,7 +798,7 @@ Name: QWindowsMobileStyle
SeeAlso: ???
Feature: STYLE_STYLESHEET
-Description:
+Description:
Section: Styles
Requires: STYLE_WINDOWS PROPERTIES CSSPARSER
Name: QStyleSheetStyle
@@ -809,14 +809,14 @@ SeeAlso: ???
Feature: IMAGEFORMATPLUGIN
Description: Supports writing an image format plugin.
Section: Images
-Requires:
+Requires:
Name: QImageIOPlugin
SeeAlso: ???
Feature: ICON
Description: Supports scalable icons in different modes and states.
Section: Images
-Requires:
+Requires:
Name: QIcon
SeeAlso: ???
@@ -837,14 +837,14 @@ SeeAlso: ???
Feature: IMAGEFORMAT_PPM
Description: Supports the Portable Pixmap image file format.
Section: Images
-Requires:
+Requires:
Name: PPM Image Format
SeeAlso: ???
Feature: IMAGEFORMAT_XBM
Description: Supports the X11 Bitmap image file format.
Section: Images
-Requires:
+Requires:
Name: XBM Image Format
SeeAlso: ???
@@ -858,14 +858,14 @@ SeeAlso: ???
Feature: IMAGEFORMAT_PNG
Description: Supports the Portable Network Graphics image file format.
Section: Images
-Requires:
+Requires:
Name: PNG Image Format
SeeAlso: ???
Feature: IMAGEFORMAT_JPEG
Description: Supports the Joint Photographic Experts Group image file format.
Section: Images
-Requires:
+Requires:
Name: JPEG Image Format
SeeAlso: ???
@@ -895,7 +895,7 @@ SeeAlso: ???
Feature: PICTURE
Description: Supports recording and replaying QPainter commands.
Section: Painting
-Requires:
+Requires:
Name: QPicture
SeeAlso: ???
@@ -908,9 +908,9 @@ Name: Color Names
SeeAlso: ???
Feature: PRINTER
-Description: Supports printing
+Description: Supports printing
Section: Painting
-Requires: TEXTSTREAM
+Requires: TEXTSTREAM PICTURE
Name: QPrinter
SeeAlso: ???
@@ -952,7 +952,7 @@ Name: Freetype Font Engine
SeeAlso: ???
Feature: QWS_QPF
-Description: Supports Qt's pre-rendered fonts, a light-weight non-scalable font format
+Description: Supports Qt's pre-rendered fonts, a light-weight non-scalable font format
specific to Qt for Embedded Linux.
Section: Fonts
Requires:
@@ -960,7 +960,7 @@ Name: Qt Prerendered Font Format
SeeAlso: ???
Feature: QWS_QPF2
-Description: Supports Qt's second generation of pre-rendered fonts, a light-weight
+Description: Supports Qt's second generation of pre-rendered fonts, a light-weight
non-scalable font format specific to Qt for Embedded Linux.
Section: Fonts
Requires:
@@ -987,7 +987,7 @@ Feature: TRANSLATION_UTF8
Description: Supports translations using QObject::trUtf8().
Section: Internationalization
Requires: TRANSLATION TEXTCODEC
-Name: Translation (UTF-8 representation)
+Name: Translation (UTF-8 representation)
SeeAlso: ???
Feature: TEXTCODEC
@@ -1007,14 +1007,14 @@ SeeAlso: ???
Feature: BIG_CODECS
Description: Supports big codecs, e.g. CJK.
Section: Internationalization
-Requires:
+Requires:
Name: Big Codecs
SeeAlso: ???
Feature: QWS_INPUTMETHODS
Description: Supports international input methods.
Section: Internationalization
-Requires:
+Requires:
Name: QWSInputMethod
SeeAlso: ???
@@ -1023,14 +1023,14 @@ SeeAlso: ???
Feature: URLINFO
Description: Supports storage of URL information.
Section: Networking
-Requires:
+Requires:
Name: QUrlInfo
SeeAlso: ???
Feature: HOSTINFO
Description: Supports host name lookups.
Section: Networking
-Requires: TEXTSTREAM
+Requires: TEXTSTREAM
Name: QHostInfo
SeeAlso: ???
@@ -1051,14 +1051,14 @@ SeeAlso: ???
Feature: UDPSOCKET
Description: Supports User Datagram Protocol sockets.
Section: Networking
-Requires:
+Requires:
Name: QUdpSocket
SeeAlso: ???
Feature: NETWORKPROXY
Description: Supports configuring network layer proxy support to the Qt network classes.
Section: Networking
-Requires:
+Requires:
Name: QNetworkProxy
SeeAlso: ???
@@ -1123,7 +1123,7 @@ Name: QUndoStack
SeeAlso: ???
Feature: UNDOGROUP
-Description:
+Description:
Section: Utilities
Requires: UNDOCOMMAND UNDOSTACK
Name: QUndoGroup
@@ -1181,7 +1181,7 @@ Name: QSvgRenderer
SeeAlso: ???
Feature: SVGWIDGET
-Description: Provides a widget that is used to display the contents of SVG files.
+Description: Provides a widget that is used to display the contents of SVG files.
Section: SVG
Requires: SVGRENDERER
Name: QSvgWidget
@@ -1233,21 +1233,21 @@ Name: Manager
SeeAlso: ???
Feature: QWS_DECORATION_DEFAULT
-Description: Supports default decoration of the top level windows.
+Description: Supports default decoration of the top level windows.
Section: Qt for Embedded Linux
-Requires:
+Requires:
Name: Decoration
SeeAlso: ???
Feature: QWS_DECORATION_WINDOWS
-Description: Supports a "Windows" style decoration of the top level windows.
+Description: Supports a "Windows" style decoration of the top level windows.
Section: Qt for Embedded Linux
Requires: QWS_DECORATION_DEFAULT
Name: Decoration (Windows Style)
SeeAlso: ???
Feature: QWS_DECORATION_STYLED
-Description: Supports styled decoration of the top level windows.
+Description: Supports styled decoration of the top level windows.
Section: Qt for Embedded Linux
Requires: QWS_DECORATION_DEFAULT
Name: Decoration (Styled)
@@ -1395,13 +1395,13 @@ SeeAlso: ???
Feature: PHONON_MEDIACONTROLLER
Description: Support for the MediaController class
Section: Phonon
-Requires:
+Requires:
Name: Phonon::MediaController
SeeAlso: ???
Feature: PHONON_ABSTRACTMEDIASTREAM
Description: Support for streaming of raw data (QIODevice...)
Section: Phonon
-Requires:
+Requires:
Name: Phonon::AbstractMediaStream
SeeAlso: ???
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index b9c2bee..8324d05 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1054,6 +1054,7 @@ bool qSharedBuild()
\value WV_XP Windows XP (operating system version 5.1)
\value WV_2003 Windows Server 2003, Windows Server 2003 R2, Windows Home Server, Windows XP Professional x64 Edition (operating system version 5.2)
\value WV_VISTA Windows Vista, Windows Server 2008 (operating system version 6.0)
+ \value WV_WINDOWS7 Windows 7 (operating system version 6.1)
Alternatively, you may use the following macros which correspond directly to the Windows operating system version number:
@@ -1062,6 +1063,7 @@ bool qSharedBuild()
\value WV_5_1 Operating system version 5.1, corresponds to Windows XP
\value WV_5_2 Operating system version 5.2, corresponds to Windows Server 2003, Windows Server 2003 R2, Windows Home Server, and Windows XP Professional x64 Edition
\value WV_6_0 Operating system version 6.0, corresponds to Windows Vista and Windows Server 2008
+ \value WV_6_1 Operating system version 6.1, corresponds to Windows 7
CE-based versions:
@@ -1095,6 +1097,7 @@ bool qSharedBuild()
\value MV_10_3 Mac OS X 10.3
\value MV_10_4 Mac OS X 10.4
\value MV_10_5 Mac OS X 10.5
+ \value MV_10_6 Mac OS X 10.6
\value MV_Unknown An unknown and currently unsupported platform
\value MV_CHEETAH Apple codename for MV_10_0
@@ -1103,6 +1106,7 @@ bool qSharedBuild()
\value MV_PANTHER Apple codename for MV_10_3
\value MV_TIGER Apple codename for MV_10_4
\value MV_LEOPARD Apple codename for MV_10_5
+ \value MV_SNOWLEOPARD Apple codename for MV_10_6
\sa WinVersion
*/
@@ -1631,16 +1635,19 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
default: // VER_PLATFORM_WIN32_NT
if (osver.dwMajorVersion < 5) {
winver = QSysInfo::WV_NT;
- } else if (osver.dwMajorVersion == 6) {
- winver = QSysInfo::WV_VISTA;
- } else if (osver.dwMinorVersion == 0) {
+ } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) {
winver = QSysInfo::WV_2000;
- } else if (osver.dwMinorVersion == 1) {
+ } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) {
winver = QSysInfo::WV_XP;
- } else if (osver.dwMinorVersion == 2) {
+ } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) {
winver = QSysInfo::WV_2003;
+ } else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0) {
+ winver = QSysInfo::WV_VISTA;
+ } else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) {
+ winver = QSysInfo::WV_WINDOWS7;
} else {
- qWarning("Qt: Untested Windows version detected!");
+ qWarning("Qt: Untested Windows version %d.%d detected!",
+ osver.dwMajorVersion, osver.dwMinorVersion);
winver = QSysInfo::WV_NT_based;
}
}
@@ -1667,6 +1674,8 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
winver = QSysInfo::WV_XP;
else if (override == "VISTA")
winver = QSysInfo::WV_VISTA;
+ else if (override == "WINDOWS7")
+ winver = QSysInfo::WV_WINDOWS7;
}
#endif
@@ -1925,9 +1934,11 @@ QString qt_error_string(int errorCode)
The message handler is a function that prints out debug messages,
warnings, critical and fatal error messages. The Qt library (debug
- version) contains hundreds of warning messages that are printed
+ mode) contains hundreds of warning messages that are printed
when internal errors (usually invalid function arguments)
- occur. If you implement your own message handler, you get total
+ occur. Qt built in release mode also contains such warnings unless
+ QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during
+ compilation. If you implement your own message handler, you get total
control of these messages.
The default message handler prints the message to the standard
@@ -2022,7 +2033,8 @@ void qt_message_output(QtMsgType msgType, const char *buf)
during compilation.
If you pass the function a format string and a list of arguments,
- it works in similar way to the C printf() function.
+ it works in similar way to the C printf() function. The format
+ should be a Latin-1 string.
Example:
@@ -2033,11 +2045,12 @@ void qt_message_output(QtMsgType msgType, const char *buf)
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25
- This syntax automatically puts a single space between each item,
- and outputs a newline at the end. It supports many C++ and Qt
- types.
+ With this syntax, the function returns a QDebug object that is
+ configured to use the QtDebugMsg message type. It automatically
+ puts a single space between each item, and outputs a newline at
+ the end. It supports many C++ and Qt types.
- To supress the output at runtime, install your own message handler
+ To suppress the output at run-time, install your own message handler
with qInstallMsgHandler().
\sa qWarning(), qCritical(), qFatal(), qInstallMsgHandler(),
@@ -2067,7 +2080,8 @@ void qDebug(const char *msg, ...)
QT_FATAL_WARNINGS is defined.
This function takes a format string and a list of arguments,
- similar to the C printf() function.
+ similar to the C printf() function. The format should be a Latin-1
+ string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26
@@ -2105,8 +2119,9 @@ void qWarning(const char *msg, ...)
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- This function takes a format string and a list of arguments, similar
- to the C printf() function.
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function. The format should be a Latin-1
+ string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28
@@ -2930,6 +2945,11 @@ bool QInternal::callFunction(InternalFunction func, void **args)
Compares the floating point value \a p1 and \a p2 and
returns \c true if they are considered equal, otherwise \c false.
+ Note that comparing values where either \a p1 or \a p2 is 0.0 will not work.
+ The solution to this is to compare against values greater than or equal to 1.0.
+
+ \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 46
+
The two numbers are compared in a relative way, where the
exactness is stronger the smaller the numbers are.
*/
@@ -2961,4 +2981,24 @@ bool QInternal::callFunction(InternalFunction func, void **args)
\snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 4
*/
+/*!
+ \macro Q_DECL_EXPORT
+ \relates <QtGlobal>
+
+ This macro marks a symbol for shared library export (see
+ \l{sharedlibrary.html}{Creating Shared Libraries}).
+
+ \sa Q_DECL_IMPORT
+*/
+
+/*!
+ \macro Q_DECL_IMPORT
+ \relates <QtGlobal>
+
+ This macro declares a symbol to be an import from a shared library (see
+ \l{sharedlibrary.html}{Creating Shared Libraries}).
+
+ \sa Q_DECL_EXPORT
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 5f7f262..025442a 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -289,6 +289,9 @@ namespace QtExperimental {}
#ifdef AUTODETECT_COCOA
# ifdef Q_OS_MAC64
# define QT_MAC_USE_COCOA 1
+# define QT_BUILD_KEY QT_BUILD_KEY_COCOA
+# else
+# define QT_BUILD_KEY QT_BUILD_KEY_CARBON
# endif
#endif
@@ -1322,6 +1325,7 @@ public:
WV_XP = 0x0030,
WV_2003 = 0x0040,
WV_VISTA = 0x0080,
+ WV_WINDOWS7 = 0x0090,
WV_NT_based = 0x00f0,
/* version numbers */
@@ -1330,6 +1334,7 @@ public:
WV_5_1 = WV_XP,
WV_5_2 = WV_2003,
WV_6_0 = WV_VISTA,
+ WV_6_1 = WV_WINDOWS7,
WV_CE = 0x0100,
WV_CENET = 0x0200,
@@ -1353,6 +1358,7 @@ public:
MV_10_3 = 0x0005,
MV_10_4 = 0x0006,
MV_10_5 = 0x0007,
+ MV_10_6 = 0x0008,
/* codenames */
MV_CHEETAH = MV_10_0,
@@ -1360,7 +1366,8 @@ public:
MV_JAGUAR = MV_10_2,
MV_PANTHER = MV_10_3,
MV_TIGER = MV_10_4,
- MV_LEOPARD = MV_10_5
+ MV_LEOPARD = MV_10_5,
+ MV_SNOWLEOPARD = MV_10_6
};
static const MacVersion MacintoshVersion;
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index fb7fa0c..a519f4a 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -280,9 +280,7 @@ public:
WindowStaysOnTopHint = 0x00040000,
// reserved for Qt3Support:
// WMouseNoMask = 0x00080000,
- WindowOkButtonHint = 0x00080000,
// WDestructiveClose = 0x00100000,
- WindowCancelButtonHint = 0x00100000,
// WStaticContents = 0x00200000,
// WGroupLeader = 0x00400000,
// WShowModal = 0x00800000,
@@ -291,7 +289,9 @@ public:
WindowStaysOnBottomHint = 0x04000000,
WindowCloseButtonHint = 0x08000000,
MacWindowToolBarButtonHint = 0x10000000,
- BypassGraphicsProxyWidget = 0x20000000
+ BypassGraphicsProxyWidget = 0x20000000,
+ WindowOkButtonHint = 0x00080000,
+ WindowCancelButtonHint = 0x00100000
#ifdef QT3_SUPPORT
,
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 0fa31f8..611b19a 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -49,3 +49,260 @@
#include "qdebug.h"
// This file is needed to force compilation of QDebug into the kernel library.
+
+/*!
+ \class QDebug
+ \ingroup io
+ \mainclass
+ \brief The QDebug class provides an output stream for debugging information.
+
+ QDebug is used whenever the developer needs to write out debugging or tracing
+ information to a device, file, string or console.
+
+ \section1 Basic Use
+
+ In the common case, it is useful to call the qDebug() function to obtain a
+ default QDebug object to use for writing debugging information.
+
+ \snippet doc/src/snippets/qdebug/qdebugsnippet.cpp 1
+
+ This constructs a QDebug object using the constructor that accepts a QtMsgType
+ value of QtDebugMsg. Similarly, the qWarning(), qCritical() and qFatal()
+ functions also return QDebug objects for the corresponding message types.
+
+ The class also provides several constructors for other situations, including
+ a constructor that accepts a QFile or any other QIODevice subclass that is
+ used to write debugging information to files and other devices. The constructor
+ that accepts a QString is used to write to a string for display or serialization.
+
+ \section1 Writing Custom Types to a Stream
+
+ Many standard types can be written to QDebug objects, and Qt provides support for
+ most Qt value types. To add support for custom types, you need to implement a
+ streaming operator, as in the following example:
+
+ \snippet doc/src/snippets/qdebug/qdebugsnippet.cpp 0
+
+ This is described in the \l{Debugging Techniques} and
+ \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
+ documents.
+*/
+
+/*!
+ \fn QDebug::QDebug(QIODevice *device)
+
+ Constructs a debug stream that writes to the given \a device.
+*/
+
+/*!
+ \fn QDebug::QDebug(QString *string)
+
+ Constructs a debug stream that writes to the given \a string.
+*/
+
+/*!
+ \fn QDebug::QDebug(QtMsgType type)
+
+ Constructs a debug stream that writes to the handler for the message type specified by \a type.
+*/
+
+/*!
+ \fn QDebug::QDebug(const QDebug &other)
+
+ Constructs a copy of the \a other debug stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator=(const QDebug &other)
+
+ Assigns the \a other debug stream to this stream and returns a reference to
+ this stream.
+*/
+
+/*!
+ \fn QDebug::~QDebug()
+
+ Flushes any pending data to be written and destroys the debug stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::space()
+
+ Writes a space character to the debug stream and returns a reference to
+ the stream.
+
+ The stream will record that the last character sent to the stream was a
+ space.
+
+ \sa nospace(), maybeSpace()
+*/
+
+/*!
+ \fn QDebug &QDebug::nospace()
+
+ Clears the stream's internal flag that records whether the last character
+ was a space and returns a reference to the stream.
+
+ \sa space(), maybeSpace()
+*/
+
+/*!
+ \fn QDebug &QDebug::maybeSpace()
+
+ Writes a space character to the debug stream, depending on the last
+ character sent to the stream, and returns a reference to the stream.
+
+ If the last character was a space character, this function writes a space
+ character to the stream; otherwise, no characters are written to the stream.
+
+ \sa space(), nospace()
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(QChar t)
+
+ Writes the character, \a t, to the stream and returns a reference to the
+ stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(QBool t)
+ \internal
+
+ Writes the boolean value, \a t, to the stream and returns a reference to the
+ stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(bool t)
+
+ Writes the boolean value, \a t, to the stream and returns a reference to the
+ stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(char t)
+
+ Writes the character, \a t, to the stream and returns a reference to the
+ stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(signed short i)
+
+ Writes the signed short integer, \a i, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(unsigned short i)
+
+ Writes then unsigned short integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(signed int i)
+
+ Writes the signed integer, \a i, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(unsigned int i)
+
+ Writes then unsigned integer, \a i, to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(signed long l)
+
+ Writes the signed long integer, \a l, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(unsigned long l)
+
+ Writes then unsigned long integer, \a l, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(qint64 i)
+
+ Writes the signed 64-bit integer, \a i, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(quint64 i)
+
+ Writes then unsigned 64-bit integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(float f)
+
+ Writes the 32-bit floating point number, \a f, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(double f)
+
+ Writes the 64-bit floating point number, \a f, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const char *s)
+
+ Writes the '\0'-terminated string, \a s, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const QString &s)
+
+ Writes the string, \a s, to the stream and returns a reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const QStringRef &s)
+
+ Writes the string reference, \a s, to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const QLatin1String &s)
+
+ Writes the Latin1-encoded string, \a s, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const QByteArray &b)
+
+ Writes the byte array, \a b, to the stream and returns a reference to the
+ stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(const void *p)
+
+ Writes a pointer, \a p, to the stream and returns a reference to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(QTextStreamFunction f)
+ \internal
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(QTextStreamManipulator m)
+ \internal
+*/
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 46c7dd8..b14f436 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -116,7 +116,9 @@ public:
QAbstractFileEngine *engine;
QStack<QAbstractFileEngineIterator *> fileEngineIterators;
QString path;
- QFileInfo fileInfo;
+ QFileInfo nextFileInfo;
+ //This fileinfo is the current that we will return from the public API
+ QFileInfo currentFileInfo;
QString currentFilePath;
QDirIterator::IteratorFlags iteratorFlags;
QDir::Filters filters;
@@ -140,8 +142,8 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList
this->filters = filters;
this->nameFilters = nameFilters;
- fileInfo.setFile(path);
- pushSubDirectory(fileInfo.isSymLink() ? fileInfo.canonicalFilePath() : path,
+ nextFileInfo.setFile(path);
+ pushSubDirectory(nextFileInfo.isSymLink() ? nextFileInfo.canonicalFilePath() : path,
nameFilters, filters);
}
@@ -160,12 +162,12 @@ void QDirIteratorPrivate::pushSubDirectory(const QString &path, const QStringLis
QDir::Filters filters)
{
if (iteratorFlags & QDirIterator::FollowSymlinks) {
- if (fileInfo.filePath() != path)
- fileInfo.setFile(path);
- if (fileInfo.isSymLink()) {
- visitedLinks << fileInfo.canonicalFilePath();
+ if (nextFileInfo.filePath() != path)
+ nextFileInfo.setFile(path);
+ if (nextFileInfo.isSymLink()) {
+ visitedLinks << nextFileInfo.canonicalFilePath();
} else {
- visitedLinks << fileInfo.absoluteFilePath();
+ visitedLinks << nextFileInfo.absoluteFilePath();
}
}
@@ -199,8 +201,8 @@ void QDirIteratorPrivate::advance()
QString subDir = it->currentFilePath();
#ifdef Q_OS_WIN
- if (fileInfo.isSymLink())
- subDir = fileInfo.canonicalFilePath();
+ if (currentFileInfo.isSymLink())
+ subDir = currentFileInfo.canonicalFilePath();
#endif
pushSubDirectory(subDir, it->nameFilters(), it->filters());
}
@@ -213,15 +215,16 @@ void QDirIteratorPrivate::advance()
while (it->hasNext()) {
it->next();
if (matchesFilters(it)) {
- fileInfo = it->currentFileInfo();
+ currentFileInfo = nextFileInfo;
+ nextFileInfo = it->currentFileInfo();
// Signal that we want to follow this entry.
- followNextDir = shouldFollowDirectory(fileInfo);
-
+ followNextDir = shouldFollowDirectory(nextFileInfo);
//We found a matching entry.
return;
} else if (iteratorFlags & QDirIterator::Subdirectories) {
QFileInfo fileInfo = it->currentFileInfo();
+
if (!shouldFollowDirectory(fileInfo))
continue;
QString subDir = it->currentFilePath();
@@ -238,6 +241,7 @@ void QDirIteratorPrivate::advance()
if (!foundDirectory)
delete fileEngineIterators.pop();
}
+ currentFileInfo = nextFileInfo;
done = true;
}
@@ -518,9 +522,7 @@ bool QDirIterator::hasNext() const
*/
QString QDirIterator::fileName() const
{
- if (d->fileInfo.path() != d->currentFilePath)
- d->fileInfo.setFile(d->currentFilePath);
- return d->fileInfo.fileName();
+ return d->currentFileInfo.fileName();
}
/*!
@@ -543,9 +545,7 @@ QString QDirIterator::filePath() const
*/
QFileInfo QDirIterator::fileInfo() const
{
- if (d->fileInfo.filePath() != d->currentFilePath)
- d->fileInfo.setFile(d->currentFilePath);
- return d->fileInfo;
+ return d->currentFileInfo;
}
/*!
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index d8f08c9..d7da800 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -712,6 +712,9 @@ QFile::rename(const QString &newName)
if(error() == QFile::NoError) {
if (fileEngine()->rename(newName)) {
unsetError();
+ // engine was able to handle the new name so we just reset it
+ fileEngine()->setFileName(newName);
+ d->fileName = newName;
return true;
}
@@ -731,10 +734,18 @@ QFile::rename(const QString &newName)
}
if (read == -1) {
d->setError(QFile::RenameError, in.errorString());
- return true;
+ error = true;
+ }
+ if(!error) {
+ if (!in.remove()) {
+ d->setError(QFile::RenameError, tr("Cannot remove source file"));
+ error = true;
+ }
}
- if(!error)
- in.remove();
+ if (error)
+ out.remove();
+ else
+ setFileName(newName);
return !error;
}
}
@@ -889,7 +900,10 @@ QFile::copy(const QString &newName)
error = true;
d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
}
-#ifndef QT_NO_TEMPORARYFILE
+#ifdef QT_NO_TEMPORARYFILE
+ if (error)
+ out.remove();
+#else
if (!error)
out.setAutoRemove(false);
#endif
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index a062317..96e0f82 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -145,7 +145,7 @@ void QFileInfoPrivate::initFileEngine(const QString &file)
bool QFileInfoPrivate::hasAccess(Access access) const
{
- if (!(data->fileEngine->fileFlags() & QAbstractFileEngine::LocalDiskFlag)) {
+ if (!(getFileFlags(QAbstractFileEngine::FileInfoAll) & QAbstractFileEngine::LocalDiskFlag)) {
switch (access) {
case ReadAccess:
return getFileFlags(QAbstractFileEngine::ReadUserPerm);
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 4445e3c..fa44531 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -316,7 +316,7 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
// qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify";
int buffSize = 0;
- ioctl(inotifyFd, FIONREAD, &buffSize);
+ ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
QVarLengthArray<char, 4096> buffer(buffSize);
buffSize = read(inotifyFd, buffer.data(), buffSize);
const char *at = buffer.data();
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 612f916..522be20 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -485,7 +485,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
QString absPath = nativeAbsoluteFilePath(path);
#if !defined(Q_OS_WINCE)
QString prefix = QLatin1String("\\\\?\\");
- if (isUncPath(path)) {
+ if (isUncPath(absPath)) {
prefix = QLatin1String("\\\\?\\UNC\\");
absPath.remove(0, 2);
}
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index a9d8ee2..a128482 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1476,11 +1476,15 @@ QByteArray QProcess::readAllStandardError()
}
/*!
- Starts the program \a program in a new process, passing the
- command line arguments in \a arguments. The OpenMode is set to \a
- mode. QProcess will immediately enter the Starting state. If the
- process starts successfully, QProcess will emit started();
- otherwise, error() will be emitted.
+ Starts the program \a program in a new process, if one is not already
+ running, passing the command line arguments in \a arguments. The OpenMode
+ is set to \a mode.
+
+ The QProcess object will immediately enter the Starting state. If the
+ process starts successfully, QProcess will emit started(); otherwise,
+ error() will be emitted. If the QProcess object is already running a
+ process, a warning may be printed at the console, and the existing
+ process will continue running.
Note that arguments that contain spaces are not passed to the
process as separate arguments.
@@ -1577,10 +1581,10 @@ static QStringList parseCombinedArgString(const QString &program)
/*!
\overload
- Starts the program \a program in a new process. \a program is a
- single string of text containing both the program name and its
- arguments. The arguments are separated by one or more
- spaces. For example:
+ Starts the program \a program in a new process, if one is not already
+ running. \a program is a single string of text containing both the
+ program name and its arguments. The arguments are separated by one or
+ more spaces. For example:
\snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 5
@@ -1589,6 +1593,9 @@ static QStringList parseCombinedArgString(const QString &program)
\snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 6
+ If the QProcess object is already running a process, a warning may be
+ printed at the console, and the existing process will continue running.
+
Note that, on Windows, quotes need to be both escaped and quoted.
For example, the above code would be specified in the following
way to ensure that \c{"My Documents"} is used as the argument to
@@ -1601,6 +1608,13 @@ static QStringList parseCombinedArgString(const QString &program)
void QProcess::start(const QString &program, OpenMode mode)
{
QStringList args = parseCombinedArgString(program);
+ if (args.isEmpty()) {
+ Q_D(QProcess);
+ d->processError = QProcess::FailedToStart;
+ setErrorString(tr("No program defined"));
+ emit error(d->processError);
+ return;
+ }
QString prog = args.first();
args.removeFirst();
@@ -1769,6 +1783,8 @@ bool QProcess::startDetached(const QString &program,
bool QProcess::startDetached(const QString &program)
{
QStringList args = parseCombinedArgString(program);
+ if (args.isEmpty())
+ return false;
QString prog = args.first();
args.removeFirst();
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 37173c8..33d4a47 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -850,10 +850,10 @@ bool QProcessPrivate::processStarted()
qint64 QProcessPrivate::bytesAvailableFromStdout() const
{
- size_t nbytes = 0;
+ int nbytes = 0;
qint64 available = 0;
if (::ioctl(stdoutChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
- available = (qint64) *((int *) &nbytes);
+ available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld", available);
#endif
@@ -862,10 +862,10 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const
qint64 QProcessPrivate::bytesAvailableFromStderr() const
{
- size_t nbytes = 0;
+ int nbytes = 0;
qint64 available = 0;
if (::ioctl(stderrChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
- available = (qint64) *((int *) &nbytes);
+ available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld", available);
#endif
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 62b4ed5..484e79a 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2330,6 +2330,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\o \c{HKEY_LOCAL_MACHINE\Software\MySoft}
\endlist
+ \note On Windows, for 32-bit programs running in WOW64 mode, settings are
+ stored in the following registry path:
+ \c{HKEY_LOCAL_MACHINE\Software\WOW6432node}.
+
If the file format is IniFormat, the following files are
used on Unix and Mac OS X:
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index 67d2eeb..a08c969 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -548,12 +548,13 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_EXPAND_SZ:
case REG_SZ: {
QString s;
- QT_WA( {
- s = QString::fromUtf16(((const ushort*)data.constData()));
- }, {
- s = QString::fromLocal8Bit(data.constData());
- } );
-
+ if (dataSize) {
+ QT_WA( {
+ s = QString::fromUtf16(((const ushort*)data.constData()));
+ }, {
+ s = QString::fromLocal8Bit(data.constData());
+ } );
+ }
if (value != 0)
*value = stringToVariant(s);
break;
@@ -561,19 +562,21 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_MULTI_SZ: {
QStringList l;
- int i = 0;
- for (;;) {
- QString s;
- QT_WA( {
- s = QString::fromUtf16((const ushort*)data.constData() + i);
- }, {
- s = QString::fromLocal8Bit(data.constData() + i);
- } );
- i += s.length() + 1;
+ if (dataSize) {
+ int i = 0;
+ for (;;) {
+ QString s;
+ QT_WA( {
+ s = QString::fromUtf16((const ushort*)data.constData() + i);
+ }, {
+ s = QString::fromLocal8Bit(data.constData() + i);
+ } );
+ i += s.length() + 1;
- if (s.isEmpty())
- break;
- l.append(s);
+ if (s.isEmpty())
+ break;
+ l.append(s);
+ }
}
if (value != 0)
*value = stringListToVariantList(l);
@@ -583,11 +586,13 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_NONE:
case REG_BINARY: {
QString s;
- QT_WA( {
- s = QString::fromUtf16((const ushort*)data.constData(), data.size()/2);
- }, {
- s = QString::fromLocal8Bit(data.constData(), data.size());
- } );
+ if (dataSize) {
+ QT_WA( {
+ s = QString::fromUtf16((const ushort*)data.constData(), data.size()/2);
+ }, {
+ s = QString::fromLocal8Bit(data.constData(), data.size());
+ } );
+ }
if (value != 0)
*value = stringToVariant(s);
break;
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 3cfce83..6a7b067 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -268,11 +268,13 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen)
/*NOTREACHED*/
}
+#ifndef Q_WS_WIN
static int qt_mkstemps(char *path, int slen)
{
int fd = 0;
return (_gettemp(path, &fd, 0, slen) ? fd : -1);
}
+#endif
//************* QTemporaryFileEngine
class QTemporaryFileEngine : public QFSFileEngine
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 5227d4f..ed9d0aa 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -1370,7 +1370,7 @@ QTextStream::FieldAlignment QTextStream::fieldAlignment() const
\snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 5
- Output:
+ The string \c s contains:
\snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 6
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index b3f9f1a..a23b2dd 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -377,6 +377,14 @@ QString qAppName()
QLibrary) can be retrieved with libraryPaths() and manipulated by
setLibraryPaths(), addLibraryPath(), and removeLibraryPath().
+ On Unix/Linux Qt is configured to use the system local settings by
+ default. This can cause a conflict when using POSIX functions, for
+ instance, when converting between data types such as floats and
+ strings, since the notation may differ between locales. To get
+ around this problem call the POSIX function setlocale(LC_NUMERIC,"C")
+ right after initializing QApplication or QCoreApplication to reset
+ the locale that is used for number formatting to "C"-locale.
+
\sa QApplication, QAbstractEventDispatcher, QEventLoop,
{Semaphores Example}, {Wait Conditions Example}
*/
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 1bddbe5..5e76976 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -267,6 +267,7 @@ public:
GrabKeyboard = 188,
UngrabKeyboard = 189,
CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window
+ MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear
Signal = 191,
StateFinished = 192,
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 20548de..3fd768a 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -242,6 +242,7 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
postEventSource = reinterpret_cast<GPostEventSource *>(g_source_new(&postEventSourceFuncs,
sizeof(GPostEventSource)));
+ postEventSource->serialNumber = 1;
g_source_set_can_recurse(&postEventSource->source, true);
g_source_attach(&postEventSource->source, mainContext);
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 880e95c..c4061f4 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -1059,11 +1059,20 @@ bool QEventDispatcherWin32::event(QEvent *e)
QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
WinTimerInfo *t = d->timerDict.value(zte->timerId());
if (t) {
+ t->inTimerEvent = true;
+
QTimerEvent te(zte->timerId());
QCoreApplication::sendEvent(t->obj, &te);
- WinTimerInfo *tn = d->timerDict.value(zte->timerId());
- if (tn && t == tn)
- QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
+
+ t = d->timerDict.value(zte->timerId());
+ if (t) {
+ if (t->interval == 0 && t->inTimerEvent) {
+ // post the next zero timer event as long as the timer was not restarted
+ QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
+ }
+
+ t->inTimerEvent = false;
+ }
}
return true;
} else if (e->type() == QEvent::Timer) {
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 719398c..b65f956 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -1007,6 +1007,11 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
a QEvent will be sent and the member is invoked as soon as the application
enters the main event loop.
+ \o If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
+ the same way as for Qt::QueuedConnection, except that the current thread
+ will block until the event is delivered. Using this connection type to
+ communicate between objects in the same thread will lead to deadlocks.
+
\o If \a type is Qt::AutoConnection, the member is invoked
synchronously if \a obj lives in the same thread as the
caller; otherwise it will invoke the member asynchronously.
@@ -1897,6 +1902,12 @@ static QByteArray qualifiedName(const QMetaEnum &e)
\ingroup objectmodel
+ Property meta-data is obtained from an object's meta-object. See
+ QMetaObject::property() and QMetaObject::propertyCount() for
+ details.
+
+ \section1 Property Meta-Data
+
A property has a name() and a type(), as well as various
attributes that specify its behavior: isReadable(), isWritable(),
isDesignable(), isScriptable(), and isStored().
@@ -1912,9 +1923,10 @@ static QByteArray qualifiedName(const QMetaEnum &e)
functions. See QObject::setProperty() and QObject::property() for
details.
- You get property meta-data through an object's meta-object. See
- QMetaObject::property() and QMetaObject::propertyCount() for
- details.
+ \section1 Copying and Assignment
+
+ QMetaProperty objects can be copied by value. However, each copy will
+ refer to the same underlying property meta-data.
\sa QMetaObject, QMetaEnum, QMetaMethod, {Qt's Property System}
*/
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index be60055..ce10bae 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -75,9 +75,9 @@ QT_BEGIN_NAMESPACE
\relates QMetaType
This macro makes the type \a Type known to QMetaType as long as it
- provides a public default constructor, a public copy constructor,
- and a public destructor. It is needed to use the type \a Type as a
- custom type in QVariant.
+ provides a public default constructor, a public copy constructor and
+ a public destructor.
+ It is needed to use the type \a Type as a custom type in QVariant.
Ideally, this macro should be placed below the declaration of
the class or struct. If that is not possible, it can be put in
@@ -1255,9 +1255,9 @@ void QMetaType::destroy(int type, void *data)
\relates QMetaType
\threadsafe
- Registers the type name \a typeName to the type \c{T}. Returns
+ Registers the type name \a typeName for the type \c{T}. Returns
the internal ID used by QMetaType. Any class or struct that has a
- public constructor, a public copy constructor, and a public
+ public default constructor, a public copy constructor and a public
destructor can be registered.
After a type has been registered, you can create and destroy
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 55cf464..05015c0 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1121,13 +1121,13 @@ bool QObject::event(QEvent *e)
QThreadData *threadData = d->threadData;
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
if (eventDispatcher) {
- // set inThreadChangeEvent to true to tell the dispatcher not to release out timer ids
- // back to the pool (since the timer ids are moving to a new thread).
- d->inThreadChangeEvent = true;
QList<QPair<int, int> > timers = eventDispatcher->registeredTimers(this);
- d->inThreadChangeEvent = false;
if (!timers.isEmpty()) {
+ // set inThreadChangeEvent to true to tell the dispatcher not to release out timer ids
+ // back to the pool (since the timer ids are moving to a new thread).
+ d->inThreadChangeEvent = true;
eventDispatcher->unregisterTimers(this);
+ d->inThreadChangeEvent = false;
QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
Q_ARG(void*, (new QList<QPair<int, int> >(timers))));
}
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index cdddf36..77d6599 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -95,8 +95,7 @@ static bool match(const uchar* found, const char* target, uint len)
// (normalize it to be without the zero-terminating symbol)
if (len > 0 && found[len-1] == '\0')
--len;
- // 0 means anything, "" means empty
- return !found || (qstrncmp((const char *)found, target, len) == 0 && target[len] == '\0');
+ return (memcmp(found, target, len) == 0 && target[len] == '\0');
}
static uint elfHash(const char *name)
@@ -765,8 +764,6 @@ void QTranslatorPrivate::clear()
}
/*!
- \since 4.5
-
Returns the translation for the key (\a context, \a sourceText,
\a disambiguation). If none is found, also tries (\a context, \a
sourceText, ""). If that still fails, returns an empty string.
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 44c4482..f426feb 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -56,7 +56,8 @@
\section1 Non-atomic convenience operators
For convenience, QAtomicInt provides integer comparison, cast, and
- assignment operators. Note that these operators are \e not atomic.
+ assignment operators. Note that a combination of these operators
+ is \e not an atomic operation.
\section1 The Atomic API
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 71ecab5..96a9940 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -96,9 +96,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true))
QMutexPool is destructed.
*/
QMutexPool::QMutexPool(bool recursive, int size)
- : count(size), recurs(recursive)
+ : mutexes(size), count(size), recurs(recursive)
{
- mutexes = new QMutex*[count];
for (int index = 0; index < count; ++index) {
mutexes[index] = 0;
}
@@ -110,13 +109,10 @@ QMutexPool::QMutexPool(bool recursive, int size)
*/
QMutexPool::~QMutexPool()
{
- QMutexLocker locker(&mutex);
for (int index = 0; index < count; ++index) {
delete mutexes[index];
mutexes[index] = 0;
}
- delete [] mutexes;
- mutexes = 0;
}
/*!
@@ -138,12 +134,9 @@ QMutex *QMutexPool::get(const void *address)
if (!mutexes[index]) {
// mutex not created, create one
-
- QMutexLocker locker(&mutex);
- // we need to check once again that the mutex hasn't been created, since
- // 2 threads could be trying to create a mutex at the same index...
- if (!mutexes[index])
- mutexes[index] = new QMutex(recurs ? QMutex::Recursive : QMutex::NonRecursive);
+ QMutex *newMutex = new QMutex(recurs ? QMutex::Recursive : QMutex::NonRecursive);
+ if (!mutexes[index].testAndSetOrdered(0, newMutex))
+ delete newMutex;
}
return mutexes[index];
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 65a3b54..1009ebb 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -53,7 +53,9 @@
// We mean it.
//
+#include "QtCore/qatomic.h"
#include "QtCore/qmutex.h"
+#include "QtCore/qvarlengtharray.h"
#ifndef QT_NO_THREAD
@@ -70,8 +72,7 @@ public:
static QMutex *globalInstanceGet(const void *address);
private:
- QMutex mutex;
- QMutex **mutexes;
+ QVarLengthArray<QAtomicPointer<QMutex>, 128> mutexes;
int count;
bool recurs;
};
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 7f87897..2fb6335 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -297,6 +297,12 @@ void QAdoptedThread::run()
priority parameter. If the thread is already running, this
function does nothing.
+ The effect of the \a priority parameter is dependent on the
+ operating system's scheduling policy. In particular, the \a priority
+ will be ignored on systems that do not support thread priorities
+ (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler
+ for more details).
+
\sa run(), terminate()
*/
@@ -590,6 +596,12 @@ void QThread::cleanup()
The \a priority argument can be any value in the \c
QThread::Priority enum except for \c InheritPriorty.
+ The effect of the \a priority parameter is dependent on the
+ operating system's scheduling policy. In particular, the \a priority
+ will be ignored on systems that do not support thread priorities
+ (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler
+ for more details).
+
\sa Priority priority() start()
*/
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index a3cbecc..c454224 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -652,7 +652,7 @@ QLinkedListData QLinkedListData::shared_null = {
Constructs an uninitialized iterator.
Functions like operator*() and operator++() should not be called
- on an uninitialized iterartor. Use operator=() to assign a value
+ on an uninitialized iterator. Use operator=() to assign a value
to it before using it.
\sa QLinkedList::begin() QLinkedList::end()
@@ -858,7 +858,7 @@ QLinkedListData QLinkedListData::shared_null = {
Constructs an uninitialized iterator.
Functions like operator*() and operator++() should not be called
- on an uninitialized iterartor. Use operator=() to assign a value
+ on an uninitialized iterator. Use operator=() to assign a value
to it before using it.
\sa QLinkedList::constBegin() QLinkedList::constEnd()
diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp
index 2b1c086..d7c39a7 100644
--- a/src/corelib/tools/qlistdata.cpp
+++ b/src/corelib/tools/qlistdata.cpp
@@ -1193,7 +1193,7 @@ void **QListData::erase(void **xi)
Constructs an uninitialized iterator.
Functions like operator*() and operator++() should not be called
- on an uninitialized iterartor. Use operator=() to assign a value
+ on an uninitialized iterator. Use operator=() to assign a value
to it before using it.
\sa QList::begin() QList::end()
@@ -1416,7 +1416,7 @@ void **QListData::erase(void **xi)
Constructs an uninitialized iterator.
Functions like operator*() and operator++() should not be called
- on an uninitialized iterartor. Use operator=() to assign a value
+ on an uninitialized iterator. Use operator=() to assign a value
to it before using it.
\sa QList::constBegin() QList::constEnd()
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index db2fc26..559ba81 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -4399,7 +4399,8 @@ double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
+ group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0.0;
@@ -4411,7 +4412,8 @@ qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
+ group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
@@ -4424,7 +4426,8 @@ qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (!numberToCLocale(group().unicode() == 0xa0 ? number.trimmed() : number,
+ group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index d8a9923..c3a989e 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -842,15 +842,19 @@ QT_BEGIN_NAMESPACE
*/
void QtSharedPointer::internalSafetyCheckAdd(const volatile void *ptr)
{
- QMutexLocker lock(&knownPointers()->mutex);
+ KnownPointers *const kp = knownPointers();
+ if (!kp)
+ return; // end-game: the application is being destroyed already
+
+ QMutexLocker lock(&kp->mutex);
void *actual = const_cast<void*>(ptr);
- if (knownPointers()->values.contains(actual)) {
+ if (kp->values.contains(actual)) {
printBacktrace(knownPointers()->values.value(actual));
qFatal("QSharedPointerData: internal self-check failed: pointer %p was already tracked "
"by another QSharedPointerData object", actual);
}
- knownPointers()->values.insert(actual, saveBacktrace());
+ kp->values.insert(actual, saveBacktrace());
}
/*!
@@ -858,9 +862,13 @@ void QtSharedPointer::internalSafetyCheckAdd(const volatile void *ptr)
*/
void QtSharedPointer::internalSafetyCheckRemove(const volatile void *ptr)
{
- QMutexLocker lock(&knownPointers()->mutex);
+ KnownPointers *const kp = knownPointers();
+ if (!kp)
+ return; // end-game: the application is being destroyed already
+
+ QMutexLocker lock(&kp->mutex);
void *actual = const_cast<void*>(ptr);
- knownPointers()->values.remove(actual);
+ kp->values.remove(actual);
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 1b29adc..375d672 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -579,7 +579,7 @@ const QString::Null QString::null = { };
'\\0' character for a null string (\e not a null pointer), and
QString() compares equal to QString(""). We recommend that you
always use the isEmpty() function and avoid isNull().
-
+
\section1 Argument Formats
In member functions where an argument \e format can be specified
@@ -1433,7 +1433,7 @@ QString &QString::append(QChar ch)
truncated at the specified \a position.
\snippet doc/src/snippets/qstring/main.cpp 37
-
+
\sa insert(), replace()
*/
QString &QString::remove(int pos, int len)
@@ -1552,7 +1552,7 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size)
return *this;
if (pos + len > d->size)
len = d->size - pos;
-
+
uint index = pos;
replace_helper(&index, 1, len, unicode, size);
return *this;
@@ -1561,15 +1561,13 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size)
/*!
\fn QString &QString::replace(int position, int n, QChar after)
\overload replace()
-
+
Replaces \a n characters beginning at index \a position with the
character \a after and returns a reference to this string.
*/
QString &QString::replace(int pos, int len, QChar after)
{
- uint index = pos;
- replace_helper(&index, 1, len, &after, 1);
- return *this;
+ return replace(pos, len, &after, 1);
}
/*!
@@ -1602,7 +1600,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
{
if (blen == alen) {
detach();
- for (int i = 0; i < nIndices; ++i)
+ for (int i = 0; i < nIndices; ++i)
memcpy(d->data + indices[i], after, alen * sizeof(QChar));
} else if (alen < blen) {
detach();
@@ -1633,7 +1631,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
int newLen = d->size + adjust;
int moveend = d->size;
resize(newLen);
-
+
while (nIndices) {
--nIndices;
int movestart = indices[nIndices] + blen;
@@ -1685,7 +1683,7 @@ QString &QString::replace(const QChar *before, int blen,
memcpy(copy, before, blen*sizeof(QChar));
b = copy;
}
-
+
QStringMatcher matcher(b, blen, cs);
int index = 0;
@@ -1712,7 +1710,7 @@ QString &QString::replace(const QChar *before, int blen,
// index has to be adjusted in case we get back into the loop above.
index += pos*(alen-blen);
}
-
+
if (a != after)
::free((QChar *)a);
if (b != before)
@@ -2250,7 +2248,7 @@ int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs)
QVarLengthArray<ushort> s(len);
for (int i = 0; i < len; ++i)
s[i] = str.latin1()[i];
-
+
return qFindString(unicode(), length(), from, (const QChar *)s.data(), len, cs);
}
@@ -2346,7 +2344,7 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee
/*
See indexOf() for explanations.
*/
-
+
const ushort *end = haystack;
haystack += from;
const int sl_minus_1 = sl-1;
@@ -2408,7 +2406,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
const int sl = str.d->size;
if (sl == 1)
return lastIndexOf(QChar(str.d->data[0]), from, cs);
-
+
const int l = d->size;
if (from < 0)
from += l;
@@ -2446,7 +2444,7 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity
const int sl = qstrlen(str.latin1());
if (sl == 1)
return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
-
+
const int l = d->size;
if (from < 0)
from += l;
@@ -4864,7 +4862,8 @@ QString QString::toUpper() const
a pointer to a zero-terminated array of unicode characters of type
ushort (as returned by QString::utf16()).
- \note This function expects a UTF-8 string for %s.
+ \note This function expects a UTF-8 string for %s and Latin-1 for
+ the format string.
The format string supports most of the conversion specifiers
provided by printf() in the standard C++ library. It doesn't
@@ -5994,7 +5993,7 @@ QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersi
}
if (simple)
return *this;
-
+
QString s = *this;
if (version != CURRENT_VERSION) {
for (int i = 0; i < NumNormalizationCorrections; ++i) {
@@ -6206,7 +6205,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f
/*!
Returns a copy of this string with the lowest numbered place marker
replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99.
-
+
\a fieldWidth specifies the minimum amount of space that argument \a
a shall occupy. If \a a requires less space than \a fieldWidth, it
is padded to \a fieldWidth with character \a fillChar. A positive
@@ -6818,7 +6817,7 @@ void QString::updateProperties() const
Appends the given \a ch character onto the end of this string.
*/
-/*!
+/*!
\fn std::string QString::toStdString() const
Returns a std::string object with the data contained in this
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 6bea03b..3fd52ee 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -98,6 +98,8 @@ struct QVectorTypedData
T array[1];
};
+class QRegion;
+
template <typename T>
class QVector
{
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index bff4e15..ff1a01f 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -2792,9 +2792,9 @@ QStringRef QXmlStreamReader::documentEncoding() const
\inmodule QtXml
\ingroup xml-tools
- QXmlStreamWriter is the pendent to QXmlStreamReader for writing
+ QXmlStreamWriter is the counterpart to QXmlStreamReader for writing
XML. Like its related class, it operates on a QIODevice specified
- with setDevice(). The API is simple and straight forward: For every
+ with setDevice(). The API is simple and straightforward: for every
XML token or event you want to write, the writer provides a
specialized function.
@@ -2814,6 +2814,15 @@ QStringRef QXmlStreamReader::documentEncoding() const
writeStartElement(). A convenience method writeTextElement() can be
used for writing terminal elements that contain nothing but text.
+ The following abridged code snippet shows the basic use of the class
+ to write formatted XML with indentation:
+
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp start stream
+ \dots
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp write element
+ \dots
+ \snippet doc/src/snippets/qxmlstreamwriter/main.cpp finish stream
+
QXmlStreamWriter takes care of prefixing namespaces, all you have to
do is specify the \c namespaceUri when writing elements or
attributes. If you must conform to certain prefixes, you can force
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 91b9cb1..8c701f5 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -137,6 +137,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
if (!q_dbus_timeout_get_enabled(timeout))
return true;
+ QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) {
// correct thread
return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout));
@@ -152,7 +153,6 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
static bool qDBusRealAddTimeout(QDBusConnectionPrivate *d, DBusTimeout *timeout, int ms)
{
- QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
Q_ASSERT(d->timeouts.keys(timeout).isEmpty());
int timerId = d->startTimer(ms);
@@ -921,10 +921,9 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
rootNode(QString(QLatin1Char('/')))
{
static const bool threads = qDBusInitThreads();
- static const int debugging = qgetenv("QDBUS_DEBUG").toInt();
+ static const int debugging = ::isDebugging = qgetenv("QDBUS_DEBUG").toInt();
Q_UNUSED(threads)
- ::isDebugging = debugging;
#ifdef QDBUS_THREAD_DEBUG
if (debugging > 1)
qdbusThreadDebug = qdbusDefaultThreadDebug;
@@ -1036,15 +1035,16 @@ void QDBusConnectionPrivate::customEvent(QEvent *e)
QDBusLockerBase::BeforeDeliver, this);
switch (ev->subtype)
{
- case QDBusConnectionCallbackEvent::AddTimeout:
+ case QDBusConnectionCallbackEvent::AddTimeout: {
+ QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this);
while (!timeoutsPendingAdd.isEmpty()) {
QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst();
qDBusRealAddTimeout(this, entry.first, entry.second);
}
break;
+ }
case QDBusConnectionCallbackEvent::KillTimer:
- qDebug() << QThread::currentThread() << "RemoveTimeout: killing timer" << (ev->timerId & 0xffffff);
killTimer(ev->timerId);
break;
diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h
index 3880a7f..5ec9800 100644
--- a/src/dbus/qdbuspendingreply.h
+++ b/src/dbus/qdbuspendingreply.h
@@ -95,7 +95,7 @@ namespace QDBusPendingReplyTypes {
enum { Total = Next::Total + 1 };
static inline void fillMetaTypes(int *p)
{
- *p = metaTypeFor<T1>();
+ *p = metaTypeFor<T1>(0);
Next::fillMetaTypes(++p);
}
};
@@ -171,7 +171,7 @@ public:
Q_ASSERT_X(Index < count() && Index >= 0, "QDBusPendingReply::argumentAt",
"Index out of bounds");
typedef typename Select<Index>::Type ResultType;
- return qdbus_cast<ResultType>(argumentAt(Index));
+ return qdbus_cast<ResultType>(argumentAt(Index), 0);
}
inline typename Select<0>::Type value() const
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index 715bd6f..20d819f 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -92,9 +92,10 @@ enum ThreadAction {
PendingCallBlockAction = 28,
AddTimeoutAction = 50,
- RemoveTimeoutAction = 51,
- KillTimerAction = 52,
- TimerEventAction = 53,
+ RealAddTimeoutAction = 51,
+ RemoveTimeoutAction = 52,
+ KillTimerAction = 58,
+ TimerEventAction = 59,
AddWatchAction = 60,
RemoveWatchAction = 61,
ToggleWatchAction = 62,
diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/gui/accessible/qaccessible_mac.mm
index b6412c2..68efb8f 100644
--- a/src/gui/accessible/qaccessible_mac.mm
+++ b/src/gui/accessible/qaccessible_mac.mm
@@ -72,55 +72,36 @@ typedef NSString * const QAXRoleType;
#define QAXApplicationRole NSAccessibilityApplicationRole
#define QAXButtonRole NSAccessibilityButtonRole
#define QAXCancelAction NSAccessibilityCancelAction
-#define QAXCancelAction NSAccessibilityCancelAction
#define QAXCheckBoxRole NSAccessibilityCheckBoxRole
#define QAXChildrenAttribute NSAccessibilityChildrenAttribute
-#define QAXChildrenAttribute NSAccessibilityChildrenAttribute
-#define QAXChildrenAttribute NSAccessibilityChildrenAttribute
#define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
#define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
#define QAXColumnRole NSAccessibilityColumnRole
#define QAXConfirmAction NSAccessibilityConfirmAction
-#define QAXConfirmAction NSAccessibilityConfirmAction
#define QAXContentsAttribute NSAccessibilityContentsAttribute
-#define QAXContentsAttribute NSAccessibilityContentsAttribute
-#define QAXDecrementAction NSAccessibilityDecrementAction
#define QAXDecrementAction NSAccessibilityDecrementAction
#define QAXDecrementArrowSubrole NSAccessibilityDecrementArrowSubrole
#define QAXDecrementPageSubrole NSAccessibilityDecrementPageSubrole
#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
-#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
-#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
-#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
-#define QAXEnabledAttribute NSAccessibilityEnabledAttribute
#define QAXEnabledAttribute NSAccessibilityEnabledAttribute
#define QAXExpandedAttribute NSAccessibilityExpandedAttribute
#define QAXFocusedAttribute NSAccessibilityFocusedAttribute
-#define QAXFocusedAttribute NSAccessibilityFocusedAttribute
-#define QAXFocusedAttribute NSAccessibilityFocusedAttribute
#define QAXFocusedUIElementChangedNotification NSAccessibilityFocusedUIElementChangedNotification
#define QAXFocusedWindowChangedNotification NSAccessibilityFocusedWindowChangedNotification
#define QAXGroupRole NSAccessibilityGroupRole
#define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute
-#define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute
#define QAXGrowAreaRole NSAccessibilityGrowAreaRole
#define QAXHelpAttribute NSAccessibilityHelpAttribute
-#define QAXHelpAttribute NSAccessibilityHelpAttribute
-#define QAXHelpAttribute NSAccessibilityHelpAttribute
#define QAXHorizontalOrientationValue NSAccessibilityHorizontalOrientationValue
#define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute
-#define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute
-#define QAXIncrementAction NSAccessibilityIncrementAction
#define QAXIncrementAction NSAccessibilityIncrementAction
#define QAXIncrementArrowSubrole NSAccessibilityIncrementArrowSubrole
#define QAXIncrementPageSubrole NSAccessibilityIncrementPageSubrole
#define QAXIncrementorRole NSAccessibilityIncrementorRole
#define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute
-#define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute
#define QAXListRole NSAccessibilityListRole
#define QAXMainAttribute NSAccessibilityMainAttribute
#define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute
-#define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute
#define QAXMenuBarRole NSAccessibilityMenuBarRole
#define QAXMenuButtonRole NSAccessibilityMenuButtonRole
#define QAXMenuClosedNotification NSAccessibilityMenuClosedNotification
@@ -128,151 +109,90 @@ typedef NSString * const QAXRoleType;
#define QAXMenuOpenedNotification NSAccessibilityMenuOpenedNotification
#define QAXMenuRole NSAccessibilityMenuRole
#define QAXMinValueAttribute NSAccessibilityMinValueAttribute
-#define QAXMinValueAttribute NSAccessibilityMinValueAttribute
#define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute
-#define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute
-#define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute
#define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute
#define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute
-#define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute
-#define QAXOrientationAttribute NSAccessibilityOrientationAttribute
-#define QAXOrientationAttribute NSAccessibilityOrientationAttribute
#define QAXOrientationAttribute NSAccessibilityOrientationAttribute
#define QAXParentAttribute NSAccessibilityParentAttribute
#define QAXPickAction NSAccessibilityPickAction
-#define QAXPickAction NSAccessibilityPickAction
#define QAXPopUpButtonRole NSAccessibilityPopUpButtonRole
#define QAXPositionAttribute NSAccessibilityPositionAttribute
-#define QAXPositionAttribute NSAccessibilityPositionAttribute
-#define QAXPressAction NSAccessibilityPressAction
#define QAXPressAction NSAccessibilityPressAction
#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute
-#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute
-#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute
#define QAXProgressIndicatorRole NSAccessibilityProgressIndicatorRole
#define QAXRadioButtonRole NSAccessibilityRadioButtonRole
#define QAXRoleAttribute NSAccessibilityRoleAttribute
-#define QAXRoleAttribute NSAccessibilityRoleAttribute
#define QAXRoleDescriptionAttribute NSAccessibilityRoleDescriptionAttribute
#define QAXRowRole NSAccessibilityRowRole
#define QAXRowsAttribute NSAccessibilityRowsAttribute
-#define QAXRowsAttribute NSAccessibilityRowsAttribute
-#define QAXScrollAreaRole NSAccessibilityScrollAreaRole
-#define QAXScrollAreaRole NSAccessibilityScrollAreaRole
#define QAXScrollAreaRole NSAccessibilityScrollAreaRole
#define QAXScrollBarRole NSAccessibilityScrollBarRole
#define QAXSelectedAttribute NSAccessibilitySelectedAttribute
#define QAXSelectedChildrenAttribute NSAccessibilitySelectedChildrenAttribute
#define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute
-#define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute
-#define QAXSizeAttribute NSAccessibilitySizeAttribute
#define QAXSizeAttribute NSAccessibilitySizeAttribute
#define QAXSliderRole NSAccessibilitySliderRole
#define QAXSplitGroupRole NSAccessibilitySplitGroupRole
#define QAXSplitterRole NSAccessibilitySplitterRole
-#define QAXSplitterRole NSAccessibilitySplitterRole
-#define QAXSplitterRole NSAccessibilitySplitterRole
-#define QAXSplittersAttribute NSAccessibilitySplittersAttribute
#define QAXSplittersAttribute NSAccessibilitySplittersAttribute
#define QAXStaticTextRole NSAccessibilityStaticTextRole
-#define QAXStaticTextRole NSAccessibilityStaticTextRole
-#define QAXSubroleAttribute NSAccessibilitySubroleAttribute
#define QAXSubroleAttribute NSAccessibilitySubroleAttribute
#define QAXSubroleAttribute NSAccessibilitySubroleAttribute
#define QAXTabGroupRole NSAccessibilityTabGroupRole
-#define QAXTabGroupRole NSAccessibilityTabGroupRole
#define QAXTableRole NSAccessibilityTableRole
#define QAXTabsAttribute NSAccessibilityTabsAttribute
-#define QAXTabsAttribute NSAccessibilityTabsAttribute
#define QAXTextFieldRole NSAccessibilityTextFieldRole
-#define QAXTextFieldRole NSAccessibilityTextFieldRole
-#define QAXTitleAttribute NSAccessibilityTitleAttribute
-#define QAXTitleAttribute NSAccessibilityTitleAttribute
#define QAXTitleAttribute NSAccessibilityTitleAttribute
-#define QAXTitleAttribute NSAccessibilityTitleAttribute
-#define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute
#define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute
#define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute
-#define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute
#define QAXToolbarRole NSAccessibilityToolbarRole
#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute
-#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute
-#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute
-#define QAXUnknownRole NSAccessibilityUnknownRole
#define QAXUnknownRole NSAccessibilityUnknownRole
#define QAXValueAttribute NSAccessibilityValueAttribute
-#define QAXValueAttribute NSAccessibilityValueAttribute
-#define QAXValueAttribute NSAccessibilityValueAttribute
-#define QAXValueAttribute NSAccessibilityValueAttribute
#define QAXValueChangedNotification NSAccessibilityValueChangedNotification
#define QAXValueIndicatorRole NSAccessibilityValueIndicatorRole
#define QAXVerticalOrientationValue NSAccessibilityVerticalOrientationValue
#define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute
-#define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute
#define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute
-#define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute
-#define QAXWindowAttribute NSAccessibilityWindowAttribute
-#define QAXWindowAttribute NSAccessibilityWindowAttribute
#define QAXWindowAttribute NSAccessibilityWindowAttribute
#define QAXWindowCreatedNotification NSAccessibilityWindowCreatedNotification
#define QAXWindowMovedNotification NSAccessibilityWindowMovedNotification
#define QAXWindowRole NSAccessibilityWindowRole
#define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute
-#define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute
#else
typedef CFStringRef const QAXRoleType;
#define QAXApplicationRole kAXApplicationRole
#define QAXButtonRole kAXButtonRole
#define QAXCancelAction kAXCancelAction
-#define QAXCancelAction kAXCancelAction
#define QAXCheckBoxRole kAXCheckBoxRole
#define QAXChildrenAttribute kAXChildrenAttribute
-#define QAXChildrenAttribute kAXChildrenAttribute
-#define QAXChildrenAttribute kAXChildrenAttribute
-#define QAXCloseButtonAttribute kAXCloseButtonAttribute
#define QAXCloseButtonAttribute kAXCloseButtonAttribute
#define QAXColumnRole kAXColumnRole
#define QAXConfirmAction kAXConfirmAction
-#define QAXConfirmAction kAXConfirmAction
#define QAXContentsAttribute kAXContentsAttribute
-#define QAXContentsAttribute kAXContentsAttribute
-#define QAXDecrementAction kAXDecrementAction
#define QAXDecrementAction kAXDecrementAction
#define QAXDecrementArrowSubrole kAXDecrementArrowSubrole
#define QAXDecrementPageSubrole kAXDecrementPageSubrole
#define QAXDescriptionAttribute kAXDescriptionAttribute
-#define QAXDescriptionAttribute kAXDescriptionAttribute
-#define QAXDescriptionAttribute kAXDescriptionAttribute
-#define QAXDescriptionAttribute kAXDescriptionAttribute
-#define QAXEnabledAttribute kAXEnabledAttribute
#define QAXEnabledAttribute kAXEnabledAttribute
#define QAXExpandedAttribute kAXExpandedAttribute
#define QAXFocusedAttribute kAXFocusedAttribute
-#define QAXFocusedAttribute kAXFocusedAttribute
-#define QAXFocusedAttribute kAXFocusedAttribute
#define QAXFocusedUIElementChangedNotification kAXFocusedUIElementChangedNotification
#define QAXFocusedWindowChangedNotification kAXFocusedWindowChangedNotification
#define QAXGroupRole kAXGroupRole
#define QAXGrowAreaAttribute kAXGrowAreaAttribute
-#define QAXGrowAreaAttribute kAXGrowAreaAttribute
#define QAXGrowAreaRole kAXGrowAreaRole
#define QAXHelpAttribute kAXHelpAttribute
-#define QAXHelpAttribute kAXHelpAttribute
-#define QAXHelpAttribute kAXHelpAttribute
#define QAXHorizontalOrientationValue kAXHorizontalOrientationValue
#define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute
-#define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute
-#define QAXIncrementAction kAXIncrementAction
#define QAXIncrementAction kAXIncrementAction
#define QAXIncrementArrowSubrole kAXIncrementArrowSubrole
#define QAXIncrementPageSubrole kAXIncrementPageSubrole
#define QAXIncrementorRole kAXIncrementorRole
#define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute
-#define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute
#define QAXListRole kAXListRole
#define QAXMainAttribute kAXMainAttribute
#define QAXMaxValueAttribute kAXMaxValueAttribute
-#define QAXMaxValueAttribute kAXMaxValueAttribute
#define QAXMenuBarRole kAXMenuBarRole
#define QAXMenuButtonRole kAXMenuButtonRole
#define QAXMenuClosedNotification kAXMenuClosedNotification
@@ -280,97 +200,55 @@ typedef CFStringRef const QAXRoleType;
#define QAXMenuOpenedNotification kAXMenuOpenedNotification
#define QAXMenuRole kAXMenuRole
#define QAXMinValueAttribute kAXMinValueAttribute
-#define QAXMinValueAttribute kAXMinValueAttribute
#define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute
-#define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute
-#define QAXMinimizedAttribute kAXMinimizedAttribute
#define QAXMinimizedAttribute kAXMinimizedAttribute
#define QAXNextContentsAttribute kAXNextContentsAttribute
-#define QAXNextContentsAttribute kAXNextContentsAttribute
-#define QAXOrientationAttribute kAXOrientationAttribute
-#define QAXOrientationAttribute kAXOrientationAttribute
#define QAXOrientationAttribute kAXOrientationAttribute
#define QAXParentAttribute kAXParentAttribute
#define QAXPickAction kAXPickAction
-#define QAXPickAction kAXPickAction
#define QAXPopUpButtonRole kAXPopUpButtonRole
#define QAXPositionAttribute kAXPositionAttribute
-#define QAXPositionAttribute kAXPositionAttribute
-#define QAXPressAction kAXPressAction
#define QAXPressAction kAXPressAction
#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute
-#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute
-#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute
#define QAXProgressIndicatorRole kAXProgressIndicatorRole
#define QAXRadioButtonRole kAXRadioButtonRole
#define QAXRoleAttribute kAXRoleAttribute
-#define QAXRoleAttribute kAXRoleAttribute
#define QAXRoleDescriptionAttribute kAXRoleDescriptionAttribute
#define QAXRowRole kAXRowRole
#define QAXRowsAttribute kAXRowsAttribute
-#define QAXRowsAttribute kAXRowsAttribute
-#define QAXScrollAreaRole kAXScrollAreaRole
-#define QAXScrollAreaRole kAXScrollAreaRole
#define QAXScrollAreaRole kAXScrollAreaRole
#define QAXScrollBarRole kAXScrollBarRole
#define QAXSelectedAttribute kAXSelectedAttribute
#define QAXSelectedChildrenAttribute kAXSelectedChildrenAttribute
#define QAXSelectedRowsAttribute kAXSelectedRowsAttribute
-#define QAXSelectedRowsAttribute kAXSelectedRowsAttribute
-#define QAXSizeAttribute kAXSizeAttribute
#define QAXSizeAttribute kAXSizeAttribute
#define QAXSliderRole kAXSliderRole
#define QAXSplitGroupRole kAXSplitGroupRole
#define QAXSplitterRole kAXSplitterRole
-#define QAXSplitterRole kAXSplitterRole
-#define QAXSplitterRole kAXSplitterRole
-#define QAXSplittersAttribute kAXSplittersAttribute
#define QAXSplittersAttribute kAXSplittersAttribute
#define QAXStaticTextRole kAXStaticTextRole
-#define QAXStaticTextRole kAXStaticTextRole
-#define QAXSubroleAttribute kAXSubroleAttribute
#define QAXSubroleAttribute kAXSubroleAttribute
-#define QAXSubroleAttribute kAXSubroleAttribute
-#define QAXTabGroupRole kAXTabGroupRole
#define QAXTabGroupRole kAXTabGroupRole
#define QAXTableRole kAXTableRole
#define QAXTabsAttribute kAXTabsAttribute
-#define QAXTabsAttribute kAXTabsAttribute
-#define QAXTextFieldRole kAXTextFieldRole
#define QAXTextFieldRole kAXTextFieldRole
#define QAXTitleAttribute kAXTitleAttribute
-#define QAXTitleAttribute kAXTitleAttribute
-#define QAXTitleAttribute kAXTitleAttribute
-#define QAXTitleAttribute kAXTitleAttribute
#define QAXTitleUIElementAttribute kAXTitleUIElementAttribute
-#define QAXTitleUIElementAttribute kAXTitleUIElementAttribute
-#define QAXToolbarButtonAttribute kAXToolbarButtonAttribute
#define QAXToolbarButtonAttribute kAXToolbarButtonAttribute
#define QAXToolbarRole kAXToolbarRole
#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute
-#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute
-#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute
#define QAXUnknownRole kAXUnknownRole
-#define QAXUnknownRole kAXUnknownRole
-#define QAXValueAttribute kAXValueAttribute
-#define QAXValueAttribute kAXValueAttribute
-#define QAXValueAttribute kAXValueAttribute
#define QAXValueAttribute kAXValueAttribute
#define QAXValueChangedNotification kAXValueChangedNotification
#define QAXValueIndicatorRole kAXValueIndicatorRole
#define QAXVerticalOrientationValue kAXVerticalOrientationValue
#define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute
-#define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute
-#define QAXVisibleRowsAttribute kAXVisibleRowsAttribute
#define QAXVisibleRowsAttribute kAXVisibleRowsAttribute
#define QAXWindowAttribute kAXWindowAttribute
-#define QAXWindowAttribute kAXWindowAttribute
-#define QAXWindowAttribute kAXWindowAttribute
#define QAXWindowCreatedNotification kAXWindowCreatedNotification
#define QAXWindowMovedNotification kAXWindowMovedNotification
#define QAXWindowRole kAXWindowRole
#define QAXZoomButtonAttribute kAXZoomButtonAttribute
-#define QAXZoomButtonAttribute kAXZoomButtonAttribute
#endif
diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp
index 4b2b2ab..753ac57 100644
--- a/src/gui/accessible/qaccessiblewidget.cpp
+++ b/src/gui/accessible/qaccessiblewidget.cpp
@@ -131,9 +131,16 @@ QString Q_GUI_EXPORT qt_accHotKey(const QString &text)
int fa = 0;
QChar ac;
while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) {
- if (fa == text.length() - 1 || text.at(fa+1) != QLatin1Char('&')) {
- ac = text.at(fa+1);
- break;
+ ++fa;
+ if (fa < text.length()) {
+ // ignore "&&"
+ if (text.at(fa) == QLatin1Char('&')) {
+ ++fa;
+ continue;
+ } else {
+ ac = text.at(fa);
+ break;
+ }
}
}
if (ac.isNull())
diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp
index b744dca..3aa04f6 100644
--- a/src/gui/dialogs/qcolordialog.cpp
+++ b/src/gui/dialogs/qcolordialog.cpp
@@ -1523,10 +1523,10 @@ static const Qt::WindowFlags DefaultWindowFlags =
If you require a modeless dialog, use the QColorDialog constructor.
\endomit
- The static getColor() function shows the dialog, and allows the
- user to specify a color. The getRgba() function does the same, but
- also allows the user to specify a color with an alpha channel
- (transparency) value.
+ The static getColor() function shows the dialog, and allows the user to
+ specify a color. This function can also be used to let users choose a
+ color with a level of transparency: pass the ShowAlphaChannel option as
+ an additional argument.
The user can store customCount() different custom colors. The
custom colors are shared by all color dialogs, and remembered
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 9a03f2d..f70669c 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -780,6 +780,13 @@ void QFileDialog::selectFile(const QString &filename)
if (QFileInfo(filename).isAbsolute()) {
QString current = d->rootPath();
text.remove(current);
+ if (text.at(0) == QDir::separator()
+#ifdef Q_OS_WIN
+ //On Windows both cases can happen
+ || text.at(0) == QLatin1Char('/')
+#endif
+ )
+ text = text.remove(0,1);
}
if (!isVisible() || !d->lineEdit()->hasFocus())
d->lineEdit()->setText(text);
@@ -950,25 +957,29 @@ void QFileDialog::setNameFilters(const QStringList &filters)
{
Q_D(QFileDialog);
d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)")));
- d->nameFilters = filters;
+ QStringList cleanedFilters;
+ for (int i = 0; i < filters.count(); ++i) {
+ cleanedFilters << filters[i].simplified();
+ }
+ d->nameFilters = cleanedFilters;
if (d->nativeDialogInUse){
- d->setNameFilters_sys(filters);
+ d->setNameFilters_sys(cleanedFilters);
return;
}
d->qFileDialogUi->fileTypeCombo->clear();
- if (filters.isEmpty())
+ if (cleanedFilters.isEmpty())
return;
if (testOption(HideNameFilterDetails)) {
QStringList strippedFilters;
- for (int i = 0; i < filters.count(); ++i) {
- strippedFilters.append(filters[i].mid(0, filters[i].indexOf(QLatin1String(" ("))));
+ for (int i = 0; i < cleanedFilters.count(); ++i) {
+ strippedFilters.append(cleanedFilters[i].mid(0, cleanedFilters[i].indexOf(QLatin1String(" ("))));
}
d->qFileDialogUi->fileTypeCombo->addItems(strippedFilters);
} else {
- d->qFileDialogUi->fileTypeCombo->addItems(filters);
+ d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters);
}
d->_q_useNameFilter(0);
}
@@ -1582,7 +1593,12 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
args.parent = parent;
args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
+ //If workingDirectory returned a different path than the initial one,
+ //it means that the initial path was invalid. There is no point to try select a file
+ if (args.directory != QFileInfo(dir).path())
+ args.selection = QString();
+ else
+ args.selection = QFileDialogPrivate::initialSelection(dir);
args.filter = filter;
args.mode = ExistingFile;
args.options = options;
@@ -1667,7 +1683,12 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
args.parent = parent;
args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
+ //If workingDirectory returned a different path than the initial one,
+ //it means that the initial path was invalid. There is no point to try select a file
+ if (args.directory != QFileInfo(dir).path())
+ args.selection = QString();
+ else
+ args.selection = QFileDialogPrivate::initialSelection(dir);
args.filter = filter;
args.mode = ExistingFiles;
args.options = options;
@@ -1753,7 +1774,12 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
args.parent = parent;
args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
+ //If workingDirectory returned a different path than the initial one,
+ //it means that the initial path was invalid. There is no point to try select a file
+ if (args.directory != QFileInfo(dir).path())
+ args.selection = QString();
+ else
+ args.selection = QFileDialogPrivate::initialSelection(dir);
args.filter = filter;
args.mode = AnyFile;
args.options = options;
@@ -2117,6 +2143,7 @@ void QFileDialogPrivate::createWidgets()
#ifndef QT_NO_COMPLETER
completer = new QFSCompletor(model, q);
qFileDialogUi->fileNameEdit->setCompleter(completer);
+ completer->sourceModel = model;
QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
q, SLOT(_q_autoCompleteFileName(QString)));
#endif // QT_NO_COMPLETER
@@ -2239,12 +2266,21 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
proxyModel->setSourceModel(d->model);
d->qFileDialogUi->listView->setModel(d->proxyModel);
d->qFileDialogUi->treeView->setModel(d->proxyModel);
+#ifndef QT_NO_COMPLETER
+ d->completer->setModel(d->proxyModel);
+ d->completer->proxyModel = d->proxyModel;
+#endif
connect(d->proxyModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
this, SLOT(_q_rowsInserted(const QModelIndex &)));
} else {
d->proxyModel = 0;
d->qFileDialogUi->listView->setModel(d->model);
d->qFileDialogUi->treeView->setModel(d->model);
+#ifndef QT_NO_COMPLETER
+ d->completer->setModel(d->model);
+ d->completer->sourceModel = d->model;
+ d->completer->proxyModel = 0;
+#endif
connect(d->model, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
this, SLOT(_q_rowsInserted(const QModelIndex &)));
}
@@ -2757,8 +2793,9 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
{
Q_Q(QFileDialog);
// My Computer or a directory
- QString path = index.data(QFileSystemModel::FilePathRole).toString();
- if (path.isEmpty() || model->isDir(index)) {
+ QModelIndex sourceIndex = mapToSource(index);
+ QString path = sourceIndex.data(QFileSystemModel::FilePathRole).toString();
+ if (path.isEmpty() || model->isDir(sourceIndex)) {
q->setDirectory(path);
emit q->directoryEntered(path);
if (fileMode == QFileDialog::Directory
@@ -3132,7 +3169,11 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
QString QFSCompletor::pathFromIndex(const QModelIndex &index) const
{
- const QFileSystemModel *dirModel = static_cast<const QFileSystemModel *>(model());
+ const QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<const QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
QString currentLocation = dirModel->rootPath();
QString path = index.data(QFileSystemModel::FilePathRole).toString();
if (!currentLocation.isEmpty() && path.startsWith(currentLocation)) {
@@ -3178,7 +3219,11 @@ QStringList QFSCompletor::splitPath(const QString &path) const
bool startsFromRoot = path[0] == sep[0];
#endif
if (parts.count() == 1 || (parts.count() > 1 && !startsFromRoot)) {
- const QFileSystemModel *dirModel = static_cast<const QFileSystemModel *>(model());
+ const QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<const QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
QString currentLocation = QDir::toNativeSeparators(dirModel->rootPath());
if (currentLocation.contains(sep) && path != currentLocation) {
QStringList currentLocationList = splitPath(currentLocation);
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 4c13d01..90af9fc 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -278,7 +278,7 @@ QT_USE_NAMESPACE
{
Q_UNUSED(sender);
QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename);
- QFileInfo info(qtFileName);
+ QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
QString path = info.absolutePath();
if (path != *mLastFilterCheckPath){
*mLastFilterCheckPath = path;
diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h
index 8cb2cb0..dc24390 100644
--- a/src/gui/dialogs/qfiledialog_p.h
+++ b/src/gui/dialogs/qfiledialog_p.h
@@ -91,6 +91,26 @@ class QCompleter;
class QHBoxLayout;
class Ui_QFileDialog;
+#ifndef QT_NO_COMPLETER
+/*!
+ QCompleter that can deal with QFileSystemModel
+ */
+class QFSCompletor : public QCompleter {
+public:
+ QFSCompletor(QAbstractItemModel *model, QObject *parent = 0) : QCompleter(model, parent), proxyModel(0), sourceModel(0)
+ {
+#ifdef Q_OS_WIN
+ setCaseSensitivity(Qt::CaseInsensitive);
+#endif
+ }
+ QString pathFromIndex(const QModelIndex &index) const;
+ QStringList splitPath(const QString& path) const;
+
+ QAbstractProxyModel *proxyModel;
+ QFileSystemModel *sourceModel;
+};
+#endif // QT_NO_COMPLETER
+
struct QFileDialogArgs
{
QFileDialogArgs() : parent(0), mode(QFileDialog::AnyFile) {}
@@ -255,7 +275,7 @@ public:
// data
QStringList watching;
QFileSystemModel *model;
- QCompleter *completer;
+ QFSCompletor *completer;
QFileDialog::FileMode fileMode;
QFileDialog::AcceptMode acceptMode;
@@ -434,23 +454,6 @@ inline QString QFileDialogPrivate::rootPath() const {
inline QString QFileDialogPrivate::selectedNameFilter_sys() const { return QString(); }
#endif
-#ifndef QT_NO_COMPLETER
-/*!
- QCompleter that can deal with QFileSystemModel
- */
-class QFSCompletor : public QCompleter {
-public:
- QFSCompletor(QAbstractItemModel *model, QObject *parent = 0) : QCompleter(model, parent)
- {
-#ifdef Q_OS_WIN
- setCaseSensitivity(Qt::CaseInsensitive);
-#endif
- }
- QString pathFromIndex(const QModelIndex &index) const;
- QStringList splitPath(const QString& path) const;
-};
-#endif // QT_NO_COMPLETER
-
QT_END_NAMESPACE
#endif // QT_NO_FILEDIALOG
diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp
index 3fe64ff..23a2cbc 100644
--- a/src/gui/dialogs/qfileinfogatherer.cpp
+++ b/src/gui/dialogs/qfileinfogatherer.cpp
@@ -168,6 +168,20 @@ void QFileInfoGatherer::clear()
}
/*
+ Remove a \a path from the watcher
+
+ \sa listed()
+*/
+void QFileInfoGatherer::removePath(const QString &path)
+{
+#ifndef QT_NO_FILESYSTEMWATCHER
+ mutex.lock();
+ watcher->removePath(path);
+ mutex.unlock();
+#endif
+}
+
+/*
List all files in \a directoryPath
\sa listed()
@@ -286,15 +300,9 @@ QString QFileInfoGatherer::translateDriveName(const QFileInfo &drive) const
void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &files)
{
#ifndef QT_NO_FILESYSTEMWATCHER
- //### We test here if the path still exist before adding it in the watcher
- //### because sometime the file is deleted just before enter here so QStringList files is not up to date
- //### It is not a proper fix, perhaps in 4.6 we should have a better way to avoid that
- //### to ensure the gatherer have fresh information
- QFileInfo info(path);
if (files.isEmpty()
&& !watcher->directories().contains(path)
&& !path.isEmpty()
- && info.exists()
&& !path.startsWith(QLatin1String("//")) /*don't watch UNC path*/) {
watcher->addPath(path);
}
diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/gui/dialogs/qfileinfogatherer_p.h
index eac0d46..60b9d5f 100644
--- a/src/gui/dialogs/qfileinfogatherer_p.h
+++ b/src/gui/dialogs/qfileinfogatherer_p.h
@@ -161,6 +161,7 @@ public:
~QFileInfoGatherer();
void clear();
+ void removePath(const QString &path);
QExtendedInformation getInfo(const QFileInfo &info) const;
public Q_SLOTS:
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp
index 5f375b5..012d3a1 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/gui/dialogs/qfilesystemmodel.cpp
@@ -166,6 +166,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) const
{
//### TODO optim
QString path = filePath(aindex);
+ QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+ d->fileInfoGatherer.removePath(path);
QDirIterator it(path,
QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories);
@@ -375,7 +377,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
if (!info.exists())
return rootNode;
QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this);
- p->addNode(rootNode, host);
+ p->addNode(rootNode, host,info);
p->addVisibleFiles(rootNode, QStringList(host));
}
r = rootNode->visibleLocation(host);
@@ -395,6 +397,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
#endif
QFileSystemModelPrivate::QFileSystemNode *parent = node(index);
+
for (int i = 0; i < pathElements.count(); ++i) {
QString element = pathElements.at(i);
#ifdef Q_OS_WIN
@@ -423,7 +426,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
if (!info.exists())
return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root);
QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this);
- node = p->addNode(parent, element);
+ node = p->addNode(parent, element,info);
#ifndef QT_NO_FILESYSTEMWATCHER
node->populate(fileInfoGatherer.getInfo(info));
#endif
@@ -843,7 +846,7 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
QFileSystemModelPrivate::QFileSystemNode *parentNode = indexNode->parent;
int visibleLocation = parentNode->visibleLocation(parentNode->children.value(indexNode->fileName)->fileName);
- d->addNode(parentNode, newName);
+ d->addNode(parentNode, newName,indexNode->info->fileInfo());
parentNode->visibleChildren.removeAt(visibleLocation);
QFileSystemModelPrivate::QFileSystemNode * oldValue = parentNode->children.value(oldName);
parentNode->children[newName] = oldValue;
@@ -1076,11 +1079,10 @@ private:
/*
\internal
- Sort all of the children of parent (including their children)
+ Sort all of the children of parent
*/
-void QFileSystemModelPrivate::sortChildren(int column, Qt::SortOrder order, const QModelIndex &parent)
+void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent)
{
- Q_Q(QFileSystemModel);
QFileSystemModelPrivate::QFileSystemNode *indexNode = node(parent);
if (indexNode->children.count() == 0)
return;
@@ -1104,9 +1106,6 @@ void QFileSystemModelPrivate::sortChildren(int column, Qt::SortOrder order, cons
indexNode->visibleChildren.append(values.at(i).first->fileName);
values.at(i).first->isVisible = true;
}
-
- for (int i = 0; i < q->rowCount(parent); ++i)
- sortChildren(column, order, q->index(i, 0, parent));
}
/*!
@@ -1128,7 +1127,7 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
if (!(d->sortColumn == column && d->sortOrder != order && !d->forceSort)) {
//we sort only from where we are, don't need to sort all the model
- d->sortChildren(column, order, index(rootPath()));
+ d->sortChildren(column, index(rootPath()));
d->sortColumn = column;
d->forceSort = false;
}
@@ -1286,7 +1285,7 @@ QModelIndex QFileSystemModel::mkdir(const QModelIndex &parent, const QString &na
if (!dir.mkdir(name))
return QModelIndex();
QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(parent);
- d->addNode(parentNode, name);
+ d->addNode(parentNode, name, QFileInfo());
Q_ASSERT(parentNode->children.contains(name));
QFileSystemModelPrivate::QFileSystemNode *node = parentNode->children[name];
node->populate(d->fileInfoGatherer.getInfo(QFileInfo(dir.absolutePath() + QDir::separator() + name)));
@@ -1431,7 +1430,10 @@ void QFileSystemModel::setFilter(QDir::Filters filters)
}
/*!
- Returns the filter specification for the directory model.
+ Returns the filter specified for the directory model.
+
+ If a filter has not been set, the default filter is QDir::AllEntries |
+ QDir::NoDotAndDotDot | QDir::AllDirs.
\sa QDir::Filters
*/
@@ -1605,10 +1607,13 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
*WARNING* this will change the count of children
*/
-QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFileSystemNode *parentNode, const QString &fileName)
+QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFileSystemNode *parentNode, const QString &fileName, const QFileInfo& info)
{
// In the common case, itemLocation == count() so check there first
QFileSystemModelPrivate::QFileSystemNode *node = new QFileSystemModelPrivate::QFileSystemNode(fileName, parentNode);
+#ifndef QT_NO_FILESYSTEMWATCHER
+ node->populate(info);
+#endif
parentNode->children.insert(fileName, node);
return node;
}
@@ -1726,7 +1731,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QL
QExtendedInformation info = fileInfoGatherer.getInfo(updates.at(i).second);
bool previouslyHere = parentNode->children.contains(fileName);
if (!previouslyHere) {
- addNode(parentNode, fileName);
+ addNode(parentNode, fileName, info.fileInfo());
}
QFileSystemModelPrivate::QFileSystemNode * node = parentNode->children.value(fileName);
bool isCaseSensitive = parentNode->caseSensitive();
diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h
index 95fbe20..77c35a2 100644
--- a/src/gui/dialogs/qfilesystemmodel_p.h
+++ b/src/gui/dialogs/qfilesystemmodel_p.h
@@ -182,7 +182,7 @@ public:
QList<QString> visibleChildren;
QFileSystemNode *parent;
- private:
+
QExtendedInformation *info;
};
@@ -216,10 +216,10 @@ public:
bool filtersAcceptsNode(const QFileSystemNode *node) const;
bool passNameFilters(const QFileSystemNode *node) const;
void removeNode(QFileSystemNode *parentNode, const QString &name);
- QFileSystemNode* addNode(QFileSystemNode *parentNode, const QString &fileName);
+ QFileSystemNode* addNode(QFileSystemNode *parentNode, const QString &fileName, const QFileInfo &info);
void addVisibleFiles(QFileSystemNode *parentNode, const QStringList &newFiles);
void removeVisibleFile(QFileSystemNode *parentNode, int visibleLocation);
- void sortChildren(int column, Qt::SortOrder order, const QModelIndex &parent);
+ void sortChildren(int column, const QModelIndex &parent);
inline int translateVisibleLocation(QFileSystemNode *parent, int row) const {
return (sortOrder == Qt::AscendingOrder) ? row : parent->visibleChildren.count() - row - 1;
diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/gui/dialogs/qinputdialog.cpp
index b63c8ee..78d99e3 100644
--- a/src/gui/dialogs/qinputdialog.cpp
+++ b/src/gui/dialogs/qinputdialog.cpp
@@ -424,26 +424,27 @@ void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
/*!
\class QInputDialog
- \brief The QInputDialog class provides a simple convenience dialog to get a single value from the user.
+ \brief The QInputDialog class provides a simple convenience dialog to get a
+ single value from the user.
\ingroup dialogs
\mainclass
- The input value can be a string, a number or an item from a list. A
- label must be set to tell the user what they should enter.
+ The input value can be a string, a number or an item from a list. A label
+ must be set to tell the user what they should enter.
- Four static convenience functions are provided:
- getText(), getInt(), getDouble(), and getItem(). All the
- functions can be used in a similar way, for example:
+ Four static convenience functions are provided: getText(), getInt(),
+ getDouble(), and getItem(). All the functions can be used in a similar way,
+ for example:
\snippet examples/dialogs/standarddialogs/dialog.cpp 3
- The \c ok variable is set to true if the user clicks \gui OK;
- otherwise it is set to false.
+ The \c ok variable is set to true if the user clicks \gui OK; otherwise it
+ is set to false.
\img inputdialogs.png Input Dialogs
- The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
- how to use QInputDialog as well as other built-in Qt dialogs.
+ The \l{dialogs/standarddialogs}{Standard Dialogs} example shows how to use
+ QInputDialog as well as other built-in Qt dialogs.
\sa QMessageBox, {Standard Dialogs Example}
*/
@@ -452,11 +453,13 @@ void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
\enum QInputDialog::InputMode
\since 4.5
- This enum describes the different modes of input that can be selected for the dialog.
+ This enum describes the different modes of input that can be selected for
+ the dialog.
\value TextInput Used to input text strings.
\value IntInput Used to input integers.
- \value DoubleInput Used to input floating point numbers with double precision accuracy.
+ \value DoubleInput Used to input floating point numbers with double
+ precision accuracy.
\sa inputMode
*/
@@ -487,7 +490,8 @@ QInputDialog::~QInputDialog()
\brief the mode used for input
- This property help determines which widget is used for entering input into the dialog.
+ This property help determines which widget is used for entering input into
+ the dialog.
*/
void QInputDialog::setInputMode(InputMode mode)
{
@@ -1104,15 +1108,18 @@ void QInputDialog::done(int result)
}
/*!
- Static convenience function to get a string from the user. \a
- title is the text which is displayed in the title bar of the
- dialog. \a label is the text which is shown to the user (it should
- say what should be entered). \a text is the default text which is
- placed in the line edit. The \a mode is the echo mode the line
- edit will use. If \a ok is nonnull \e *\a ok will be set to true
- if the user pressed \gui OK and to false if the user pressed
- \gui Cancel. The dialog's parent is \a parent. The dialog will be
- modal and uses the specified widget \a flags.
+ Static convenience function to get a string from the user.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a text is the default text which is placed in the line edit.
+ \a mode is the echo mode the line edit will use.
+
+ If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ \gui OK and to false if the user pressed \gui Cancel. The dialog's parent
+ is \a parent. The dialog will be modal and uses the specified widget
+ \a flags.
This function returns the text which has been entered in the line
edit. It will not return an empty string.
@@ -1121,11 +1128,11 @@ void QInputDialog::done(int result)
\snippet examples/dialogs/standarddialogs/dialog.cpp 3
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QInputDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
- \sa getInteger(), getDouble(), getItem()
+ \sa getInt(), getDouble(), getItem()
*/
QString QInputDialog::getText(QWidget *parent, const QString &title, const QString &label,
@@ -1149,30 +1156,32 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
}
/*!
- Static convenience function to get an integer input from the
- user. \a title is the text which is displayed in the title bar
- of the dialog. \a label is the text which is shown to the user
- (it should say what should be entered). \a value is the default
- integer which the spinbox will be set to. \a min and \a
- max are the minimum and maximum values the user may choose,
- and \a step is the amount by which the values change as the user
- presses the arrow buttons to increment or decrement the value.
-
- If \a ok is nonnull *\a ok will be set to true if the user
- pressed \gui OK and to false if the user pressed \gui Cancel. The
- dialog's parent is \a parent. The dialog will be modal and uses
- the widget \a flags.
-
- On success, this function returns the integer which has been
- entered by the user; on failure, it returns the initial \a value.
+ \since 4.5
+
+ Static convenience function to get an integer input from the user.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a value is the default integer which the spinbox will be set to.
+ \a min and \a max are the minimum and maximum values the user may choose.
+ \a step is the amount by which the values change as the user presses the
+ arrow buttons to increment or decrement the value.
+
+ If \a ok is nonnull *\a ok will be set to true if the user pressed \gui OK
+ and to false if the user pressed \gui Cancel. The dialog's parent is
+ \a parent. The dialog will be modal and uses the widget \a flags.
+
+ On success, this function returns the integer which has been entered by the
+ user; on failure, it returns the initial \a value.
Use this static function like this:
\snippet examples/dialogs/standarddialogs/dialog.cpp 0
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QInputDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
\sa getText(), getDouble(), getItem()
*/
@@ -1198,32 +1207,32 @@ int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &l
}
/*!
- Static convenience function to get a floating point number from
- the user. \a title is the text which is displayed in the title
- bar of the dialog. \a label is the text which is shown to the user
- (it should say what should be entered). \a value is the default
- floating point number that the line edit will be set to. \a
- min and \a max are the minimum and maximum values the
- user may choose, and \a decimals is the maximum number of decimal
- places the number may have.
-
- If \a ok is nonnull, *\a ok will be set to true if the user
- pressed \gui OK and to false if the user pressed \gui Cancel. The
- dialog's parent is \a parent. The dialog will be modal and uses
- the widget \a flags.
-
- This function returns the floating point number which has been
- entered by the user.
+ Static convenience function to get a floating point number from the user.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a value is the default floating point number that the line edit will be
+ set to.
+ \a min and \a max are the minimum and maximum values the user may choose.
+ \a decimals is the maximum number of decimal places the number may have.
+
+ If \a ok is nonnull, *\a ok will be set to true if the user pressed \gui OK
+ and to false if the user pressed \gui Cancel. The dialog's parent is
+ \a parent. The dialog will be modal and uses the widget \a flags.
+
+ This function returns the floating point number which has been entered by
+ the user.
Use this static function like this:
\snippet examples/dialogs/standarddialogs/dialog.cpp 1
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QInputDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
- \sa getText(), getInteger(), getItem()
+ \sa getText(), getInt(), getItem()
*/
double QInputDialog::getDouble(QWidget *parent, const QString &title, const QString &label,
@@ -1248,32 +1257,34 @@ double QInputDialog::getDouble(QWidget *parent, const QString &title, const QStr
}
/*!
- Static convenience function to let the user select an item from a
- string list. \a title is the text which is displayed in the title
- bar of the dialog. \a label is the text which is shown to the user (it
- should say what should be entered). \a items is the
- string list which is inserted into the combobox, and \a current is the number
- of the item which should be the current item. If \a editable is true
- the user can enter their own text; if \a editable is false the user
- may only select one of the existing items.
-
- If \a ok is nonnull \e *\a ok will be set to true if the user
- pressed \gui OK and to false if the user pressed \gui Cancel. The
- dialog's parent is \a parent. The dialog will be modal and uses
- the widget \a flags.
-
- This function returns the text of the current item, or if \a
- editable is true, the current text of the combobox.
+ Static convenience function to let the user select an item from a string
+ list.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a items is the string list which is inserted into the combobox.
+ \a current is the number of the item which should be the current item.
+
+ If \a editable is true the user can enter their own text; otherwise the
+ user may only select one of the existing items.
+
+ If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ \gui OK and to false if the user pressed \gui Cancel. The dialog's parent
+ is \a parent. The dialog will be modal and uses the widget \a flags.
+
+ This function returns the text of the current item, or if \a editable is
+ true, the current text of the combobox.
Use this static function like this:
\snippet examples/dialogs/standarddialogs/dialog.cpp 2
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QInputDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
- \sa getText(), getInteger(), getDouble()
+ \sa getText(), getInt(), getDouble()
*/
QString QInputDialog::getItem(QWidget *parent, const QString &title, const QString &label,
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index f343405..1967837 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -532,11 +532,11 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
\section2 Severity Levels and the Icon and Pixmap Properties
- QMessageBox supports four predefined message severity levels, or
- message types, which really only differ in the predefined icon
- they each show. Specify one of the four predefined message types
- by setting the \l{QMessageBox::icon} {icon} property to one of the
- \l{QMessageBox::Icon} {predefined Icons}. The following rules are
+ QMessageBox supports four predefined message severity levels, or message
+ types, which really only differ in the predefined icon they each show.
+ Specify one of the four predefined message types by setting the
+ \l{QMessageBox::icon}{icon} property to one of the
+ \l{QMessageBox::Icon}{predefined icons}. The following rules are
guidelines:
\table
@@ -558,17 +558,17 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
\o For reporting critical errors.
\endtable
- The default value is \l{QMessageBox::NoIcon} {No Icon}. The
- message boxes are otherwise the same for all cases. When using a
- standard icon, use the one recommended in the table, or use the
- one recommended by the style guidelines for your platform. If none
- of the standard icons is right for your message box, you can use a
- custom icon by setting the \l{QMessageBox::iconPixmap} {icon
- pixmap} property instead of setting the \l{QMessageBox::icon}
- {icon} property.
-
- In summary, to set an icon, use \e{either} setIcon() for one of
- the standard icons, \e{or} setIconPixmap() for a custom icon.
+ \l{QMessageBox::Icon}{Predefined icons} are not defined by QMessageBox, but
+ provided by the style. The default value is \l{QMessageBox::NoIcon}
+ {No Icon}. The message boxes are otherwise the same for all cases. When
+ using a standard icon, use the one recommended in the table, or use the
+ one recommended by the style guidelines for your platform. If none of the
+ standard icons is right for your message box, you can use a custom icon by
+ setting the \l{QMessageBox::iconPixmap}{icon pixmap} property instead of
+ setting the \l{QMessageBox::icon}{icon} property.
+
+ In summary, to set an icon, use \e{either} setIcon() for one of the
+ standard icons, \e{or} setIconPixmap() for a custom icon.
\section1 The Static Functions API
diff --git a/src/gui/dialogs/qwizard.cpp b/src/gui/dialogs/qwizard.cpp
index fcd8ccf..32395c4 100644
--- a/src/gui/dialogs/qwizard.cpp
+++ b/src/gui/dialogs/qwizard.cpp
@@ -516,6 +516,7 @@ public:
, vistaInitPending(false)
, vistaState(QVistaHelper::Dirty)
, vistaStateChanged(false)
+ , inHandleAeroStyleChange(false)
#endif
, minimumWidth(0)
, minimumHeight(0)
@@ -617,6 +618,7 @@ public:
bool vistaInitPending;
QVistaHelper::VistaState vistaState;
bool vistaStateChanged;
+ bool inHandleAeroStyleChange;
#endif
int minimumWidth;
int minimumHeight;
@@ -1459,6 +1461,10 @@ void QWizardPrivate::handleAeroStyleChange()
{
Q_Q(QWizard);
+ if (inHandleAeroStyleChange)
+ return; // prevent recursion
+ inHandleAeroStyleChange = true;
+
vistaHelper->backButton()->disconnect();
q->removeEventFilter(vistaHelper);
@@ -1493,6 +1499,8 @@ void QWizardPrivate::handleAeroStyleChange()
if (q->isVisible())
vistaHelper->setWindowPosHack();
+
+ inHandleAeroStyleChange = false;
}
#endif
diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp
index 6f32879..6741f2c 100644
--- a/src/gui/embedded/qscreen_qws.cpp
+++ b/src/gui/embedded/qscreen_qws.cpp
@@ -2038,7 +2038,8 @@ QScreen::~QScreen()
void QScreen::shutdownDevice()
{
#ifndef QT_NO_QWS_CURSOR
- qt_screencursor->hide();
+ if (qt_screencursor)
+ qt_screencursor->hide();
#endif
}
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp
index fed7aad..48fe881 100644
--- a/src/gui/embedded/qscreenlinuxfb_qws.cpp
+++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp
@@ -342,8 +342,18 @@ bool QLinuxFbScreen::connect(const QString &displaySpec)
}
dw=w;
dh=h;
- xoff += (vinfo.xres - w)/2;
- yoff += (vinfo.yres - h)/2;
+ int xxoff, yyoff;
+ if (sscanf(qwssize, "%*dx%*d+%d+%d", &xxoff, &yyoff) == 2) {
+ if (xxoff < 0 || xxoff + w > vinfo.xres)
+ xxoff = vinfo.xres - w;
+ if (yyoff < 0 || yyoff + h > vinfo.yres)
+ yyoff = vinfo.yres - h;
+ xoff += xxoff;
+ yoff += yyoff;
+ } else {
+ xoff += (vinfo.xres - w)/2;
+ yoff += (vinfo.yres - h)/2;
+ }
} else {
dw=w=vinfo.xres;
dh=h=vinfo.yres;
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index d95b194..95b2589 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -528,25 +528,22 @@ QT_BEGIN_NAMESPACE
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
-{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+static inline void _q_adjustRect(QRectF *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
}
-static QRect _q_adjustedRect(const QRect &rect)
+static inline void _q_adjustRect(QRect *rect)
{
- QRect r = rect;
- if (!r.width())
- r.adjust(0, 0, 1, 0);
- if (!r.height())
- r.adjust(0, 0, 0, 1);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(0, 0, 1, 0);
+ if (!rect->height())
+ rect->adjust(0, 0, 0, 1);
}
/*
@@ -631,6 +628,7 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
case QGraphicsItem::ItemClipsChildrenToShape:
flag = AncestorClipsChildren;
enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
+ invalidateCachedClipPathRecursively(/*childrenOnly=*/true);
break;
case QGraphicsItem::ItemIgnoresTransformations:
flag = AncestorIgnoresTransformations;
@@ -1028,9 +1026,8 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
if (parent == d_ptr->parent)
return;
- QVariant variant;
- qVariantSetValue<QGraphicsItem *>(variant, parent);
- parent = qVariantValue<QGraphicsItem *>(itemChange(ItemParentChange, variant));
+ const QVariant newParentVariant(itemChange(ItemParentChange, qVariantFromValue<QGraphicsItem *>(parent)));
+ parent = qVariantValue<QGraphicsItem *>(newParentVariant);
if (parent == d_ptr->parent)
return;
@@ -1045,11 +1042,11 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
// We anticipate geometry changes
prepareGeometryChange();
+ const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
if (d_ptr->parent) {
// Remove from current parent
qt_graphicsitem_removeChild(this, &d_ptr->parent->d_func()->children);
- qVariantSetValue<QGraphicsItem *>(variant, this);
- d_ptr->parent->itemChange(ItemChildRemovedChange, variant);
+ d_ptr->parent->itemChange(ItemChildRemovedChange, thisPointerVariant);
}
if ((d_ptr->parent = parent)) {
@@ -1064,10 +1061,9 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
d_ptr->parent->d_func()->children << this;
- qVariantSetValue<QGraphicsItem *>(variant, this);
- d_ptr->parent->itemChange(ItemChildAddedChange, variant);
+ d_ptr->parent->itemChange(ItemChildAddedChange, thisPointerVariant);
if (!implicitUpdate)
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
// Inherit ancestor flags from the new parent.
d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
@@ -1096,7 +1092,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
if (!d_ptr->enabled && !d_ptr->explicitlyDisabled)
d_ptr->setEnabledHelper(true, /* explicit = */ false);
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
}
if (d_ptr->scene) {
@@ -1106,10 +1102,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
}
// Resolve opacity.
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
+ d_ptr->updateEffectiveOpacity();
// Resolve depth.
d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1);
@@ -1118,7 +1111,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent)
d_ptr->invalidateSceneTransformCache();
// Deliver post-change notification
- itemChange(QGraphicsItem::ItemParentHasChanged, qVariantFromValue<QGraphicsItem *>(parent));
+ itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
}
/*!
@@ -1240,7 +1233,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
int geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
bool fullUpdate = (flags & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
if (fullUpdate)
- d_ptr->fullUpdateHelper();
+ d_ptr->fullUpdateHelper(false, true);
// Keep the old flags to compare the diff.
GraphicsItemFlags oldFlags = this->flags();
@@ -1250,12 +1243,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
// Reresolve effective opacity if the opacity flags change.
static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren;
- if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) {
- if (QGraphicsItem *p = d_ptr->parent)
- d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
- else
- d_ptr->resolveEffectiveOpacity(1.0);
- }
+ if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask))
+ d_ptr->updateEffectiveOpacity();
if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
// Clear focus on the item if it has focus when the focusable flag
@@ -1275,6 +1264,9 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
}
+ if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape))
+ d_ptr->invalidateCachedClipPath();
+
if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
// Item children clipping changes. Propagate the ancestor flag to
// all children.
@@ -1282,7 +1274,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
}
// ### Why updateHelper?
- d_ptr->updateHelper();
+ d_ptr->updateHelper(QRectF(), false, true);
// Notify change.
itemChange(ItemFlagsHaveChanged, quint32(flags));
@@ -1380,9 +1372,9 @@ QString QGraphicsItem::toolTip() const
*/
void QGraphicsItem::setToolTip(const QString &toolTip)
{
- QString newCursor = itemChange(ItemToolTipChange, toolTip).toString();
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTip);
- itemChange(ItemToolTipHasChanged, toolTip);
+ const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
+ itemChange(ItemToolTipHasChanged, toolTipVariant);
}
#endif // QT_NO_TOOLTIP
@@ -1424,9 +1416,8 @@ QCursor QGraphicsItem::cursor() const
*/
void QGraphicsItem::setCursor(const QCursor &cursor)
{
- QCursor newCursor = qVariantValue<QCursor>(itemChange(ItemCursorChange,
- qVariantFromValue<QCursor>(cursor)));
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, newCursor);
+ const QVariant cursorVariant(itemChange(ItemCursorChange, qVariantFromValue<QCursor>(cursor)));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue<QCursor>(cursorVariant));
d_ptr->hasCursor = 1;
if (d_ptr->scene) {
foreach (QGraphicsView *view, d_ptr->scene->views()) {
@@ -1443,7 +1434,7 @@ void QGraphicsItem::setCursor(const QCursor &cursor)
}
}
}
- itemChange(ItemCursorHasChanged, qVariantFromValue<QCursor>(newCursor));
+ itemChange(ItemCursorHasChanged, cursorVariant);
}
/*!
@@ -1537,14 +1528,20 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
return;
// Modify the property.
- newVisible = q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, quint32(newVisible)).toBool();
+ const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
+ quint32(newVisible)));
+ newVisible = newVisibleVariant.toBool();
if (visible == quint32(newVisible))
return;
visible = newVisible;
// Schedule redrawing
- if (update)
+ if (update) {
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
+ if (c)
+ c->purge();
updateHelper(QRectF(), /* force = */ true);
+ }
// Certain properties are dropped as an item becomes invisible.
if (!newVisible) {
@@ -1580,9 +1577,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Update children with explicitly = false.
+ const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
foreach (QGraphicsItem *child, children) {
if (!newVisible || !child->d_ptr->explicitlyHidden)
- child->d_ptr->setVisibleHelper(newVisible, false);
+ child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
}
// Enable subfocus
@@ -1594,7 +1592,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, quint32(visible));
+ q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
}
/*!
@@ -1700,7 +1698,9 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
}
// Modify the property.
- enabled = q_ptr->itemChange(QGraphicsItem::ItemEnabledChange, quint32(newEnabled)).toBool();
+ const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
+ quint32(newEnabled)));
+ enabled = newEnabledVariant.toBool();
// Schedule redraw.
if (update)
@@ -1712,7 +1712,7 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
}
// Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, quint32(enabled));
+ q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
}
/*!
@@ -1799,7 +1799,8 @@ void QGraphicsItem::setSelected(bool selected)
selected = false;
if (d_ptr->selected == selected)
return;
- bool newSelected = itemChange(ItemSelectedChange, quint32(selected)).toBool();
+ const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
+ bool newSelected = newSelectedVariant.toBool();
if (d_ptr->selected == newSelected)
return;
d_ptr->selected = newSelected;
@@ -1819,7 +1820,7 @@ void QGraphicsItem::setSelected(bool selected)
}
// Deliver post-change notification.
- itemChange(QGraphicsItem::ItemSelectedHasChanged, quint32(d_ptr->selected));
+ itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
}
/*!
@@ -1863,6 +1864,9 @@ qreal QGraphicsItem::opacity() const
*/
qreal QGraphicsItem::effectiveOpacity() const
{
+ if (!d_ptr->hasEffectiveOpacity)
+ return qreal(1.0);
+
QVariant effectiveOpacity = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectiveOpacity);
return effectiveOpacity.isNull() ? qreal(1.0) : qreal(effectiveOpacity.toDouble());
}
@@ -1892,7 +1896,8 @@ qreal QGraphicsItem::effectiveOpacity() const
void QGraphicsItem::setOpacity(qreal opacity)
{
// Notify change.
- qreal newOpacity = itemChange(ItemOpacityChange, double(opacity)).toDouble();
+ const QVariant newOpacityVariant(itemChange(ItemOpacityChange, double(opacity)));
+ qreal newOpacity = newOpacityVariant.toDouble();
// Normalize.
newOpacity = qBound<qreal>(0.0, newOpacity, 1.0);
@@ -2350,19 +2355,22 @@ QPointF QGraphicsItem::scenePos() const
the item is also updated; otherwise it is not updated before and after the
change.
*/
-void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
+void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
{
Q_Q(QGraphicsItem);
if (this->pos == pos)
return;
// Notify the item that the position is changing.
- QPointF newPos = q->itemChange(QGraphicsItem::ItemPositionChange, pos).toPointF();
+ const QVariant newPosVariant(q->itemChange(QGraphicsItem::ItemPositionChange, pos));
+ QPointF newPos = newPosVariant.toPointF();
if (newPos == this->pos)
return;
// Update and repositition.
- if (scene && update) {
+ inSetPosHelper = 1;
+ updateCachedClipPathFromSetPosHelper(newPos);
+ if (scene) {
fullUpdateHelper(true);
q->prepareGeometryChange();
}
@@ -2370,7 +2378,8 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
invalidateSceneTransformCache();
// Send post-notification.
- q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos);
+ q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
+ inSetPosHelper = 0;
}
/*!
@@ -2385,7 +2394,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update)
*/
void QGraphicsItem::setPos(const QPointF &pos)
{
- d_ptr->setPosHelper(pos, /* update = */ true);
+ d_ptr->setPosHelper(pos);
}
/*!
@@ -2529,10 +2538,10 @@ QTransform QGraphicsItem::sceneTransform() const
QTransform m;
if (d_ptr->hasTransform) {
m = transform();
- m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
- } else {
- // ### ? QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y())
- m.translate(d_ptr->pos.x(), d_ptr->pos.y());
+ if (!d_ptr->pos.isNull())
+ m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
+ } else if (!d_ptr->pos.isNull()) {
+ m = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
}
// Combine with parent and add to cache.
@@ -2657,6 +2666,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
if (ok)
*ok = true;
const QPointF &itemPos = d_ptr->pos;
+ if (itemPos.isNull())
+ return d_ptr->hasTransform ? transform() : QTransform();
if (d_ptr->hasTransform)
return transform() * QTransform::fromTranslate(itemPos.x(), itemPos.y());
return QTransform::fromTranslate(itemPos.x(), itemPos.y());
@@ -2667,7 +2678,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
const QPointF &otherPos = other->d_ptr->pos;
if (other->d_ptr->hasTransform) {
QTransform otherToParent = other->transform();
- otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
+ if (!otherPos.isNull())
+ otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
return otherToParent.inverted(ok);
} else {
if (ok)
@@ -2692,11 +2704,11 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
QTransform itemToParent = QTransform::fromTranslate(itemPos.x(), itemPos.y());
if (hasTr)
- itemToParent = transform() * itemToParent;
+ itemToParent = itemPos.isNull() ? transform() : transform() * itemToParent;
QTransform otherToParent = QTransform::fromTranslate(otherPos.x(), otherPos.y());
if (otherHasTr)
- otherToParent = other->transform() * otherToParent;
+ otherToParent = otherPos.isNull() ? other->transform() : other->transform() * otherToParent;
return itemToParent * otherToParent.inverted(ok);
}
@@ -2736,7 +2748,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
const QGraphicsItemPrivate *pd = p->d_ptr;
if (pd->hasTransform)
x *= p->transform();
- x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
+ if (!pd->pos.isNull())
+ x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
} while ((p = p->d_ptr->parent) && p != root);
if (parentOfOther)
return x.inverted(ok);
@@ -2781,12 +2794,11 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
QVariant variant;
qVariantSetValue<QMatrix>(variant, newTransform.toAffine());
newTransform = QTransform(qVariantValue<QMatrix>(itemChange(ItemMatrixChange, variant)));
-
if (oldTransform == newTransform)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true);
+ d_ptr->fullUpdateHelper(true, true);
prepareGeometryChange();
transformData->baseTransform = newTransform;
transformData->dirty = true;
@@ -2794,7 +2806,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
d_ptr->invalidateSceneTransformCache();
// Send post-notification.
- itemChange(ItemTransformHasChanged, newTransform);
+ // NB! We have to change the value from QMatrix to QTransform.
+ qVariantSetValue<QTransform>(newTransformVariant, newTransform);
+ itemChange(ItemTransformHasChanged, newTransformVariant);
}
/*!
@@ -2836,14 +2850,14 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
return;
// Notify the item that the transformation matrix is changing.
- QVariant variant;
- qVariantSetValue<QTransform>(variant, newTransform);
- newTransform = qVariantValue<QTransform>(itemChange(ItemTransformChange, variant));
+ const QVariant newTransformVariant(itemChange(ItemTransformChange,
+ qVariantFromValue<QTransform>(newTransform)));
+ newTransform = qVariantValue<QTransform>(newTransformVariant);
if (oldTransform == newTransform)
return;
// Update and set the new transformation.
- d_ptr->fullUpdateHelper(true);
+ d_ptr->fullUpdateHelper(true, true);
prepareGeometryChange();
transformData->baseTransform = newTransform;
transformData->dirty = true;
@@ -2852,7 +2866,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
d_ptr->invalidateSceneTransformCache();
// Send post-notification.
- itemChange(ItemTransformHasChanged, newTransform);
+ itemChange(ItemTransformHasChanged, newTransformVariant);
}
/*!
@@ -3191,7 +3205,8 @@ qreal QGraphicsItem::zValue() const
*/
void QGraphicsItem::setZValue(qreal z)
{
- qreal newZ = qreal(itemChange(ItemZValueChange, double(z)).toDouble());
+ const QVariant newZVariant(itemChange(ItemZValueChange, double(z)));
+ qreal newZ = qreal(newZVariant.toDouble());
if (newZ == d_ptr->z)
return;
d_ptr->z = z;
@@ -3203,7 +3218,7 @@ void QGraphicsItem::setZValue(qreal z)
d_ptr->scene->d_func()->invalidateSortCache();
}
- itemChange(ItemZValueHasChanged, double(newZ));
+ itemChange(ItemZValueHasChanged, newZVariant);
}
/*!
@@ -3228,7 +3243,9 @@ QRectF QGraphicsItem::childrenBoundingRect() const
QRectF childRect;
foreach (QGraphicsItem *child, children()) {
QPointF childPos = child->pos();
- QTransform matrix = child->transform() * QTransform::fromTranslate(childPos.x(), childPos.y());
+ QTransform matrix = child->transform();
+ if (!childPos.isNull())
+ matrix *= QTransform::fromTranslate(childPos.x(), childPos.y());
childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
}
return childRect;
@@ -3360,57 +3377,79 @@ bool QGraphicsItem::isClipped() const
QPainterPath QGraphicsItem::clipPath() const
{
Q_D(const QGraphicsItem);
- QPainterPath clip;
- if (!isClipped())
- return clip;
+ if (!d->dirtyClipPath)
+ return d->emptyClipPath ? QPainterPath() : d->cachedClipPath;
+
+ if (!isClipped()) {
+ d_ptr->setCachedClipPath(QPainterPath());
+ return d->cachedClipPath;
+ }
+ const QRectF thisBoundingRect(boundingRect());
+ if (thisBoundingRect.isEmpty()) {
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
+ return QPainterPath();
+ }
+
+ QPainterPath clip;
// Start with the item's bounding rect.
- clip.addRect(boundingRect());
+ clip.addRect(thisBoundingRect);
- bool clipAway = false;
if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- // Make list of parents up to the farthest ancestor that clips its
- // children to its shape.
- QVarLengthArray<const QGraphicsItem *, 32> clippingAncestors;
- const QGraphicsItem *parent = parentItem();
- const QGraphicsItem *clipOwner = 0;
- do {
+ const QGraphicsItem *parent = this;
+ const QGraphicsItem *lastParent = this;
+
+ // Intersect any in-between clips starting at the top and moving downwards.
+ bool foundValidClipPath = false;
+ while ((parent = parent->d_ptr->parent)) {
if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
- clippingAncestors.append(parent);
- clipOwner = parent;
- }
- } while ((parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) && (parent = parent->parentItem()));
+ // Map clip to the current parent and intersect with its shape/clipPath
+ clip = lastParent->itemTransform(parent).map(clip);
+ if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) {
+ if (parent->d_ptr->emptyClipPath) {
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
+ return QPainterPath();
+ }
+ clip = clip.intersected(parent->d_ptr->cachedClipPath);
+ if (!(parent->d_ptr->flags & ItemClipsToShape))
+ clip = clip.intersected(parent->shape());
+ } else {
+ clip = clip.intersected(parent->shape());
+ }
- // Start with the topmost clip.
- QPainterPath parentClip = clipOwner->shape();
+ if (clip.isEmpty()) {
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->setEmptyCachedClipPathRecursively();
+ else
+ d_ptr->setEmptyCachedClipPath();
+ return clip;
+ }
+ lastParent = parent;
+ }
- // Intersect any in-between clips starting at the bottom and moving
- // upwards.
- for (int i = clippingAncestors.size() - 2; i >= 0; --i) {
- const QGraphicsItem *item = clippingAncestors[i];
- // ### what if itemtransform fails
- if (clipOwner)
- parentClip = clipOwner->itemTransform(item).map(parentClip);
- parentClip = parentClip.intersected(item->shape());
- if (parentClip.isEmpty()) {
- clip = parentClip;
- clipAway = true;
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ || foundValidClipPath) {
break;
}
- clipOwner = item;
}
- if (!clipAway) {
+ if (lastParent != this) {
+ // Map clip back to the item's transform.
// ### what if itemtransform fails
- clip = clip.intersected(clipOwner->itemTransform(this).map(parentClip));
- if (clip.isEmpty())
- clipAway = true;
+ clip = lastParent->itemTransform(this).map(clip);
}
}
- if (!clipAway && d->flags & ItemClipsToShape)
+ if (d->flags & ItemClipsToShape)
clip = clip.intersected(shape());
+ d_ptr->setCachedClipPath(clip);
return clip;
}
@@ -3499,8 +3538,10 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
return false;
}
- QRectF rectA = _q_adjustedRect(boundingRect());
- QRectF rectB = _q_adjustedRect(path.controlPointRect());
+ QRectF rectA(boundingRect());
+ _q_adjustRect(&rectA);
+ QRectF rectB(path.controlPointRect());
+ _q_adjustRect(&rectB);
if (!rectA.intersects(rectB)) {
// This we can determine efficiently. If the two rects neither
// intersect nor contain eachother, then the two items do not collide.
@@ -3509,12 +3550,11 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
// For further testing, we need this item's shape or bounding rect.
QPainterPath thisShape;
- if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape) {
+ if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
- } else {
- thisShape.addPolygon(_q_adjustedRect(boundingRect()));
- thisShape.closeSubpath();
- }
+ else
+ thisShape.addRect(rectA);
+
if (thisShape == QPainterPath()) {
// Empty shape? No collision.
return false;
@@ -3684,7 +3724,8 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
// into the bitmap, converts the result to a QRegion and scales the region
// back to device space with inverse granularity.
qreal granularity = boundingRegionGranularity();
- QRect deviceRect = _q_adjustedRect(itemToDeviceTransform.mapRect(boundingRect()).toRect());
+ QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
+ _q_adjustRect(&deviceRect);
if (granularity == 0.0)
return QRegion(deviceRect);
@@ -3814,6 +3855,24 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
/*!
\internal
+ Returns true if we can discard an update request; otherwise false.
+*/
+bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping,
+ bool ignoreVisibleBit,
+ bool ignoreDirtyBit) const
+{
+ // No scene, or if the scene is updating everything, means we have nothing
+ // to do. The only exception is if the scene tracks the growing scene rect.
+ return (!visible && !ignoreVisibleBit)
+ || (dirty && !ignoreDirtyBit)
+ || !scene
+ || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect)
+ || (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
+ || (childrenCombineOpacity() && isFullyTransparent());
+}
+
+/*!
+ \internal
Asks the scene to mark this item's scene rect as dirty, requesting a
redraw. This does not invalidate any cache.
@@ -3822,19 +3881,16 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
only case where the item's background should be marked as dirty even when
the item isn't visible.
*/
-void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force)
+void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool maybeDirtyClipPath)
{
// No scene, or if the scene is updating everything, means we have nothing
// to do. The only exception is if the scene tracks the growing scene rect.
- if (dirty)
- return;
- if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
+ if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/force))
return;
- if (scene && (visible || force)) {
- if (rect.isNull())
- dirty = 1;
- scene->itemUpdated(q_ptr, rect);
- }
+
+ if (rect.isNull())
+ dirty = 1;
+ scene->itemUpdated(q_ptr, rect);
}
/*!
@@ -3842,21 +3898,25 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force)
Propagates updates to \a item and all its children.
*/
-void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly)
+void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath)
{
- // No scene, or if the scene is updating everything, means we have nothing
- // to do. The only exception is if the scene tracks the growing scene rect.
- if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect))
- return;
- if (!childrenOnly && !dirty)
- updateHelper();
- if (children.isEmpty() || dirtyChildren)
+ if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath,
+ /*ignoreVisibleBit=*/false,
+ /*ignoreDirtyBit=*/true)) {
return;
- if (flags & QGraphicsItem::ItemClipsChildrenToShape) {
- // ### mark all children dirty?
+ }
+
+ if (!childrenOnly && !dirty) {
+ // Effectively the same as updateHelper(QRectF(), false, maybeDirtyClipPath).
+ dirty = 1;
+ scene->itemUpdated(q_ptr, QRectF());
+ }
+
+ if (dirtyChildren || childrenClippedToShape()) {
// Unnecessary to update children as well.
return;
}
+
if (ancestorFlags & AncestorClipsChildren) {
Q_Q(QGraphicsItem);
// Check if we can avoid updating all children.
@@ -3879,10 +3939,36 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly)
}
}
foreach (QGraphicsItem *child, children)
- child->d_ptr->fullUpdateHelper();
+ child->d_ptr->fullUpdateHelper(false, maybeDirtyClipPath);
dirtyChildren = 1;
}
+static inline bool qt_allChildrenCombineOpacity(QGraphicsItem *parent)
+{
+ Q_ASSERT(parent);
+ if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
+ return false;
+
+ const QList<QGraphicsItem *> children(parent->childItems());
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity)
+ return false;
+ }
+ return true;
+}
+
+void QGraphicsItemPrivate::updateEffectiveOpacity()
+{
+ Q_Q(QGraphicsItem);
+ if (parent) {
+ resolveEffectiveOpacity(parent->effectiveOpacity());
+ parent->d_ptr->allChildrenCombineOpacity = qt_allChildrenCombineOpacity(parent);
+ } else {
+ resolveEffectiveOpacity(1.0);
+ }
+ allChildrenCombineOpacity = qt_allChildrenCombineOpacity(q);
+}
+
/*!
\internal
@@ -3907,7 +3993,14 @@ void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity)
}
// Set this item's resolved opacity.
- setExtra(ExtraEffectiveOpacity, myEffectiveOpacity);
+ if (qFuzzyCompare(myEffectiveOpacity, qreal(1.0))) {
+ // Opaque, unset effective opacity.
+ hasEffectiveOpacity = 0;
+ unsetExtra(ExtraEffectiveOpacity);
+ } else {
+ hasEffectiveOpacity = 1;
+ setExtra(ExtraEffectiveOpacity, myEffectiveOpacity);
+ }
// Resolve children always.
for (int i = 0; i < children.size(); ++i)
@@ -3960,6 +4053,109 @@ void QGraphicsItemPrivate::removeExtraItemCache()
unsetExtra(ExtraCacheData);
}
+void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect)
+{
+ setEmptyCachedClipPath();
+
+ const bool checkRect = !emptyIfOutsideThisRect.isNull()
+ && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
+ for (int i = 0; i < children.size(); ++i) {
+ if (!checkRect) {
+ children.at(i)->d_ptr->setEmptyCachedClipPathRecursively();
+ continue;
+ }
+
+ QGraphicsItem *child = children.at(i);
+ const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
+ if (rect.intersects(child->boundingRect()))
+ child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
+ else
+ child->d_ptr->setEmptyCachedClipPathRecursively(rect);
+ }
+}
+
+void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect)
+{
+ if (!childrenOnly)
+ invalidateCachedClipPath();
+
+ const bool checkRect = !emptyIfOutsideThisRect.isNull();
+ for (int i = 0; i < children.size(); ++i) {
+ if (!checkRect) {
+ children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
+ continue;
+ }
+
+ QGraphicsItem *child = children.at(i);
+ const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
+ if (rect.intersects(child->boundingRect()))
+ child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
+ else
+ child->d_ptr->setEmptyCachedClipPathRecursively(rect);
+ }
+}
+
+void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos)
+{
+ Q_ASSERT(inSetPosHelper);
+
+ if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ return; // Not clipped by any ancestor.
+
+ // Find closest clip ancestor and transform.
+ Q_Q(QGraphicsItem);
+ QTransform thisToParentTransform = hasTransform
+ ? q->transform() * QTransform::fromTranslate(newPos.x(), newPos.y())
+ : QTransform::fromTranslate(newPos.x(), newPos.y());
+ QGraphicsItem *clipParent = parent;
+ while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
+ if (clipParent->d_ptr->hasTransform)
+ thisToParentTransform *= clipParent->transform();
+ if (!clipParent->d_ptr->pos.isNull()) {
+ thisToParentTransform *= QTransform::fromTranslate(clipParent->d_ptr->pos.x(),
+ clipParent->d_ptr->pos.y());
+ }
+ clipParent = clipParent->d_ptr->parent;
+ }
+
+ // thisToParentTransform is now the same as q->itemTransform(clipParent), except
+ // that the new position (which is not yet set on the item) is taken into account.
+ Q_ASSERT(clipParent);
+ Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+
+ // From here everything is calculated in clip parent's coordinates.
+ const QRectF parentBoundingRect(clipParent->boundingRect());
+ const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect()));
+
+ if (!parentBoundingRect.intersects(thisBoundingRect)) {
+ // Item is moved outside the clip parent's bounding rect,
+ // i.e. it is fully clipped and the clip path is empty.
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape)
+ setEmptyCachedClipPathRecursively();
+ else
+ setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect));
+ return;
+ }
+
+ const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape());
+ if (parentClip.contains(thisBoundingRect))
+ return; // Item is inside the clip parent's shape. No update required.
+
+ const QRectF parentClipRect(parentClip.controlPointRect());
+ if (!parentClipRect.intersects(thisBoundingRect)) {
+ // Item is moved outside the clip parent's shape,
+ // i.e. it is fully clipped and the clip path is empty.
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape)
+ setEmptyCachedClipPathRecursively();
+ else
+ setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect));
+ } else {
+ // Item is partially inside the clip parent's shape,
+ // i.e. the cached clip path must be invalidated.
+ invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect));
+ }
+}
+
/*!
\internal
@@ -3990,20 +4186,23 @@ bool QGraphicsItemPrivate::isProxyWidget() const
*/
void QGraphicsItem::update(const QRectF &rect)
{
- if (d_ptr->dirty)
+ if ((rect.isEmpty() && !rect.isNull()) || d_ptr->discardUpdateRequest())
return;
- if (d_ptr->scene && isVisible()) {
- if (CacheMode(d_ptr->cacheMode) != NoCache) {
- QGraphicsItemCache *cache = d_ptr->extraItemCache();
- if (rect.isNull()) {
- cache->allExposed = true;
- cache->exposed.clear();
- } else {
- cache->exposed.append(rect);
- }
+
+ if (CacheMode(d_ptr->cacheMode) != NoCache) {
+ QGraphicsItemCache *cache = d_ptr->extraItemCache();
+ if (rect.isNull()) {
+ cache->allExposed = true;
+ cache->exposed.clear();
+ } else {
+ cache->exposed.append(rect);
}
- d_ptr->updateHelper(rect);
}
+
+ // Effectively the same as updateHelper(rect);
+ if (rect.isNull())
+ d_ptr->dirty = 1;
+ d_ptr->scene->itemUpdated(this, rect);
}
@@ -4260,9 +4459,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect
*/
QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
{
- if (!d_ptr->hasTransform)
- return QPolygonF(rect.translated(d_ptr->pos));
- return transform().map(rect.translated(d_ptr->pos));
+ QPolygonF p = !d_ptr->hasTransform ? rect : transform().map(rect);
+ p.translate(d_ptr->pos);
+ return p;
}
/*!
@@ -4329,8 +4528,8 @@ QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rec
*/
QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
{
- QRectF r = rect.translated(d_ptr->pos.x(), d_ptr->pos.y());
- return !d_ptr->hasTransform ? r : transform().mapRect(r);
+ QRectF r = !d_ptr->hasTransform ? rect : transform().mapRect(rect);
+ return r.translated(d_ptr->pos);
}
/*!
@@ -4461,9 +4660,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &p
*/
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
{
- QPolygonF p = polygon;
+ QPolygonF p = !d_ptr->hasTransform ? polygon : transform().map(polygon);
p.translate(d_ptr->pos);
- return d_ptr->hasTransform ? transform().map(p) : p;
+ return p;
}
/*!
@@ -4505,7 +4704,10 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP
*/
QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
{
- return d_ptr->parent ? itemTransform(d_ptr->parent).map(path) : mapToScene(path);
+ QTransform x = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
+ if (d_ptr->hasTransform)
+ x = transform() * x;
+ return x.map(path);
}
/*!
@@ -5735,11 +5937,18 @@ void QGraphicsItem::removeFromIndex()
void QGraphicsItem::prepareGeometryChange()
{
if (d_ptr->scene) {
- d_ptr->updateHelper();
-
+ d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
scenePrivate->removeFromIndex(this);
}
+
+ if (d_ptr->inSetPosHelper)
+ return;
+
+ if (d_ptr->flags & ItemClipsChildrenToShape)
+ d_ptr->invalidateCachedClipPathRecursively();
+ else
+ d_ptr->invalidateCachedClipPath();
}
/*!
@@ -7253,6 +7462,7 @@ QVariant QGraphicsLineItem::extension(const QVariant &variant) const
QPixmap::createHeuristicMask(). The performance and memory consumption
is similar to MaskShape.
*/
+extern QPainterPath qt_regionToPath(const QRegion &region);
class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
{
@@ -7273,7 +7483,6 @@ public:
void updateShape()
{
- extern QPainterPath qt_regionToPath(const QRegion &region);
shape = QPainterPath();
switch (shapeMode) {
case QGraphicsPixmapItem::MaskShape: {
@@ -8323,6 +8532,8 @@ void QGraphicsTextItem::setTabChangesFocus(bool b)
Returns true if the \gui Tab key will cause the widget to change focus;
otherwise, false is returned.
+ By default, this behavior is disabled, and this function will return false.
+
\sa setTabChangesFocus()
*/
bool QGraphicsTextItem::tabChangesFocus() const
@@ -8514,6 +8725,7 @@ void QGraphicsSimpleTextItem::setText(const QString &text)
return;
d->text = text;
d->updateBoundingRect();
+ update();
}
/*!
@@ -8775,13 +8987,17 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
QTransform oldSceneMatrix = item->sceneTransform();
item->setPos(mapFromItem(item, 0, 0));
item->setParentItem(this);
- item->setTransform(oldSceneMatrix
- * sceneTransform().inverted()
- * QTransform::fromTranslate(-item->x(), -item->y()));
+ QTransform newItemTransform(oldSceneMatrix);
+ newItemTransform *= sceneTransform().inverted();
+ if (!item->pos().isNull())
+ newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+ item->setTransform(newItemTransform);
item->d_func()->setIsMemberOfGroup(true);
prepareGeometryChange();
- d->itemsBoundingRect |= (item->transform() * QTransform::fromTranslate(item->x(), item->y()))
- .mapRect(item->boundingRect() | item->childrenBoundingRect());
+ QTransform itemTransform(item->transform());
+ if (!item->pos().isNull())
+ itemTransform *= QTransform::fromTranslate(item->x(), item->y());
+ d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
update();
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index c14b978..d2cbf25 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -142,10 +142,15 @@ public:
hasBoundingRegionGranularity(0),
flags(0),
hasOpacity(0),
+ hasEffectiveOpacity(0),
isWidget(0),
dirty(0),
dirtyChildren(0),
localCollisionHack(0),
+ dirtyClipPath(1),
+ emptyClipPath(0),
+ inSetPosHelper(0),
+ allChildrenCombineOpacity(1),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -166,11 +171,15 @@ public:
virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
static bool movableAncestorIsSelected(const QGraphicsItem *item);
- void setPosHelper(const QPointF &pos, bool update);
+ void setPosHelper(const QPointF &pos);
void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
- void updateHelper(const QRectF &rect = QRectF(), bool force = false);
- void fullUpdateHelper(bool childrenOnly = false);
+ bool discardUpdateRequest(bool ignoreClipping = false,
+ bool ignoreVisibleBit = false,
+ bool ignoreDirtyBit = false) const;
+ void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
+ void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
+ void updateEffectiveOpacity();
void resolveEffectiveOpacity(qreal effectiveParentOpacity);
void resolveDepth(int parentDepth);
void invalidateSceneTransformCache();
@@ -243,6 +252,47 @@ public:
QGraphicsItemCache *extraItemCache() const;
void removeExtraItemCache();
+ inline void setCachedClipPath(const QPainterPath &path)
+ {
+ cachedClipPath = path;
+ dirtyClipPath = 0;
+ emptyClipPath = 0;
+ }
+
+ inline void setEmptyCachedClipPath()
+ {
+ emptyClipPath = 1;
+ dirtyClipPath = 0;
+ }
+
+ void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF());
+
+ inline void invalidateCachedClipPath()
+ { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; }
+
+ void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
+ void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
+
+ inline bool isFullyTransparent() const
+ { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); }
+
+ inline bool childrenCombineOpacity() const
+ { return allChildrenCombineOpacity || children.isEmpty(); }
+
+ inline bool isClippedAway() const
+ { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
+
+ inline bool childrenClippedToShape() const
+ { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
+
+ inline bool isInvisible() const
+ {
+ return !visible
+ || (childrenClippedToShape() && isClippedAway())
+ || (childrenCombineOpacity() && isFullyTransparent());
+ }
+
+ QPainterPath cachedClipPath;
QPointF pos;
qreal z;
QGraphicsScene *scene;
@@ -272,10 +322,15 @@ public:
// New 32 bytes
quint32 hasOpacity : 1;
+ quint32 hasEffectiveOpacity : 1;
quint32 isWidget : 1;
quint32 dirty : 1;
quint32 dirtyChildren : 1;
quint32 localCollisionHack : 1;
+ quint32 dirtyClipPath : 1;
+ quint32 emptyClipPath : 1;
+ quint32 inSetPosHelper : 1;
+ quint32 allChildrenCombineOpacity : 1;
// Optional stacking order
int globalStackingOrder;
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp
index 0ea7692..eaa97ff 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem.cpp
+++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp
@@ -117,7 +117,7 @@ QGraphicsLayoutItemPrivate::QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *par,
*/
void QGraphicsLayoutItemPrivate::init()
{
- sizeHintCacheDirty = true;
+ sizeHintCacheDirty = true;
sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
@@ -175,12 +175,12 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint)
Returns the parent item of this layout, or 0 if this layout is
not installed on any widget.
-
+
If this is the item that the layout is installed on, it will return "itself".
If the layout is a sub-layout, this function returns the parent
widget of the parent layout.
-
+
Note that it will traverse up the layout item hierarchy instead of just calling
QGraphicsItem::parentItem(). This is on purpose.
@@ -233,7 +233,7 @@ QGraphicsItem *QGraphicsLayoutItemPrivate::parentItem() const
position. Calling setGeometry() will always resize and reposition the item
immediately. Normally, this function is called by QGraphicsLayout after
the layout has been activated, but it can also be called by the item's user
- at any time.
+ at any time.
The sizeHint() function returns the item' minimum, preferred and maximum
size hints. You can override these properties by calling setMinimumSize(),
@@ -360,7 +360,7 @@ void QGraphicsLayoutItem::setSizePolicy(QSizePolicy::Policy hPolicy,
}
/*!
- Returns the current size policy.
+ Returns the current size policy.
\sa setSizePolicy(), QWidget::sizePolicy()
*/
@@ -626,14 +626,15 @@ void QGraphicsLayoutItem::setMaximumHeight(qreal height)
*/
/*!
- \fn virtual void QGraphicsLayoutItem::setGeometry(const QRectF &rect) = 0
+ \fn virtual void QGraphicsLayoutItem::setGeometry(const QRectF &rect)
- This pure virtual function sets the geometry of the QGraphicsLayoutItem to
+ This virtual function sets the geometry of the QGraphicsLayoutItem to
\a rect, which is in parent coordinates (e.g., the top-left corner of \a rect
is equivalent to the item's position in parent coordinates).
- Reimplement this function in a subclass of QGraphicsLayoutItem to enable
- your item to receive geometry updates.
+ You must reimplement this function in a subclass of QGraphicsLayoutItem to
+ receive geometry updates. The layout will call this function when it does a
+ rearrangement.
If \a rect is outside of the bounds of minimumSize and maximumSize, it
will be adjusted to its closest size so that it is within the legal
@@ -744,7 +745,7 @@ QSizeF QGraphicsLayoutItem::effectiveSizeHint(Qt::SizeHint which, const QSizeF &
\sa effectiveSizeHint()
*/
void QGraphicsLayoutItem::updateGeometry()
-{
+{
Q_D(QGraphicsLayoutItem);
d->sizeHintCacheDirty = true;
}
@@ -768,7 +769,7 @@ QGraphicsLayoutItem *QGraphicsLayoutItem::parentLayoutItem() const
\sa parentLayoutItem()
*/
void QGraphicsLayoutItem::setParentLayoutItem(QGraphicsLayoutItem *parent)
-{
+{
d_func()->parent = parent;
}
@@ -789,12 +790,12 @@ bool QGraphicsLayoutItem::isLayout() const
If its true, then the layout will delete it. If its false, then it is
assumed that another object has the ownership of it, and the layout won't
delete this item.
-
- If the item inherits both QGraphicsItem and QGraphicsLayoutItem (such
- as QGraphicsWidget does) the item is really part of two ownership
+
+ If the item inherits both QGraphicsItem and QGraphicsLayoutItem (such
+ as QGraphicsWidget does) the item is really part of two ownership
hierarchies. This property informs what the layout should do with its
child items when it is destructed. In the case of QGraphicsWidget, it
- is preferred that when the layout is deleted it won't delete its children
+ is preferred that when the layout is deleted it won't delete its children
(since they are also part of the graphics item hierarchy).
By default this value is initialized to false in QGraphicsLayoutItem,
@@ -822,9 +823,9 @@ void QGraphicsLayoutItem::setOwnedByLayout(bool ownership)
/*!
* Returns the QGraphicsItem that this layout item represents.
- * For QGraphicsWidget it will return itself. For custom items it can return an
- * aggregated value.
- *
+ * For QGraphicsWidget it will return itself. For custom items it can return an
+ * aggregated value.
+ *
* \sa setGraphicsItem()
*/
QGraphicsItem *QGraphicsLayoutItem::graphicsItem() const
@@ -836,10 +837,10 @@ QGraphicsItem *QGraphicsLayoutItem::graphicsItem() const
* If the QGraphicsLayoutItem represents a QGraphicsItem, and it wants to take
* advantage of the automatic reparenting capabilities of QGraphicsLayout it
* should set this value.
- * Note that if you delete \a item and not delete the layout item, you are
- * responsible of calling setGraphicsItem(0) in order to avoid having a
+ * Note that if you delete \a item and not delete the layout item, you are
+ * responsible of calling setGraphicsItem(0) in order to avoid having a
* dangling pointer.
- *
+ *
* \sa graphicsItem()
*/
void QGraphicsLayoutItem::setGraphicsItem(QGraphicsItem *item)
@@ -848,5 +849,5 @@ void QGraphicsLayoutItem::setGraphicsItem(QGraphicsItem *item)
}
QT_END_NAMESPACE
-
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
index 1bd2e21..973254f 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp
@@ -177,6 +177,10 @@ QT_BEGIN_NAMESPACE
while the widget is embedded. In this state, the widget may differ slightly
in behavior from when it is not embedded.
+ \warning This class is provided for convenience when bridging
+ QWidgets and QGraphicsItems, it should not be used for
+ high-performance scenarios.
+
\sa QGraphicsScene::addWidget(), QGraphicsWidget
*/
@@ -1034,7 +1038,7 @@ void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
if (receiver != d->dragDropWidget) {
// Try to enter before we leave
QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
- dragEnter.setDropAction(event->proposedAction());
+ dragEnter.setDropAction(event->proposedAction());
QApplication::sendEvent(receiver, &dragEnter);
event->setAccepted(dragEnter.isAccepted());
event->setDropAction(dragEnter.dropAction());
@@ -1433,7 +1437,7 @@ int QGraphicsProxyWidget::type() const
Creates a proxy widget for the given \a child of the widget
contained in this proxy.
-
+
This function makes it possible to aquire proxies for
non top-level widgets. For instance, you can embed a dialog,
and then transform only one of its widgets.
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 1f78a18..9881960 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,15 +292,21 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
+static inline void _q_adjustRect(QRectF *rect)
{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
+}
+
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
}
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
@@ -632,10 +638,11 @@ void QGraphicsScenePrivate::_q_updateLater()
*/
void QGraphicsScenePrivate::_q_polishItems()
{
+ const QVariant booleanTrueVariant(true);
foreach (QGraphicsItem *item, unpolishedItems) {
if (!item->d_ptr->explicitlyHidden) {
- item->itemChange(QGraphicsItem::ItemVisibleChange, true);
- item->itemChange(QGraphicsItem::ItemVisibleHasChanged, true);
+ item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
+ item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
}
if (item->isWidget()) {
QEvent event(QEvent::Polish);
@@ -691,9 +698,8 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
Q_Q(QGraphicsScene);
if (QGraphicsItem *parent = item->d_func()->parent) {
- QVariant variant;
- qVariantSetValue<QGraphicsItem *>(variant, item);
- parent->itemChange(QGraphicsItem::ItemChildRemovedChange, variant);
+ parent->itemChange(QGraphicsItem::ItemChildRemovedChange,
+ qVariantFromValue<QGraphicsItem *>(item));
parent->d_func()->children.removeAll(item);
}
@@ -740,6 +746,15 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item)
unpolishedItems.removeAll(item);
dirtyItems.removeAll(item);
+ //We remove all references of item from the sceneEventFilter arrays
+ QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
+ while (iterator != sceneEventFilters.end()) {
+ if (iterator.value() == item || iterator.key() == item)
+ iterator = sceneEventFilters.erase(iterator);
+ else
+ ++iterator;
+ }
+
// Remove from scene transform cache
int transformIndex = item->d_func()->sceneTransformIndex;
if (transformIndex != -1) {
@@ -1358,6 +1373,48 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item)
return 0;
}
+
+QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPointF &pos) const
+{
+ QList<QGraphicsItem *> items;
+
+ // The index returns a rough estimate of what items are inside the rect.
+ // Refine it by iterating through all returned items.
+ QRectF adjustedRect = QRectF(pos, QSize(1,1));
+ foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
+ // Find the item's scene transform in a clever way.
+ QTransform x = item->sceneTransform();
+ bool keep = false;
+
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ const QRectF br(adjustedItemBoundingRect(item));
+ // Rect intersects/contains item's shape
+ if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok) {
+ if (item->contains(xinv.map(pos))) {
+ items << item;
+ keep = true;
+ }
+ }
+ }
+
+ if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
+ // Recurse into children that clip children.
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok)
+ childItems_helper(&items, item, xinv.map(pos));
+ }
+ }
+
+ sortItems(&items, Qt::AscendingOrder, sortCacheEnabled);
+ return items;
+}
+
QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
Qt::ItemSelectionMode mode,
Qt::SortOrder order) const
@@ -1368,7 +1425,8 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
- QRectF adjustedRect = _q_adjustedRect(rect);
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
// Find the item's scene transform in a clever way.
QTransform x = item->sceneTransform();
@@ -1377,7 +1435,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Rect intersects/contains item's bounding rect
QRectF mbr = x.mapRect(br);
@@ -1392,7 +1450,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
bool ok;
QTransform xinv = x.inverted(&ok);
if (ok) {
- if (path == QPainterPath())
+ if (path.isEmpty())
path.addRect(rect);
if (itemCollidesWithPath(item, xinv.map(path), mode)) {
items << item;
@@ -1429,7 +1487,8 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPolygonF &poly
{
QList<QGraphicsItem *> items;
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
QPainterPath path;
// The index returns a rough estimate of what items are inside the rect.
@@ -1442,7 +1501,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPolygonF &poly
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
@@ -1487,20 +1546,46 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPainterPath &p
Qt::SortOrder order) const
{
QList<QGraphicsItem *> items;
+ QRectF pathRect(path.controlPointRect());
+ _q_adjustRect(&pathRect);
+
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
- foreach (QGraphicsItem *item, estimateItemsInRect(_q_adjustedRect(path.controlPointRect()))) {
+ foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) {
// Find the item's scene transform in a clever way.
QTransform x = item->sceneTransform();
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- QPainterPath mappedPath = xinv.map(path);
- if (itemCollidesWithPath(item, mappedPath, mode)) {
+ bool keep = false;
+
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ const QRectF br(adjustedItemBoundingRect(item));
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Path contains/intersects item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) {
items << item;
- if (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)
- childItems_helper(&items, item, mappedPath, mode);
+ keep = true;
}
+ } else {
+ // Path contains/intersects item's shape
+ if (QRectF_intersects(pathRect, x.mapRect(br))) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok) {
+ if (itemCollidesWithPath(item, xinv.map(path), mode)) {
+ items << item;
+ keep = true;
+ }
+ }
+ }
+ }
+
+ if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
+ bool ok;
+ QTransform xinv = x.inverted(&ok);
+ if (ok)
+ childItems_helper(&items, item, xinv.map(path), mode);
}
}
@@ -1511,13 +1596,13 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPainterPath &p
void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
const QGraphicsItem *parent,
- const QRectF &rect,
- Qt::ItemSelectionMode mode) const
+ const QPointF &pos) const
{
- QPainterPath path;
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect()));
- if (r.isEmpty())
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
+ // ### is this needed?
+ if (parentClip && !parent->boundingRect().contains(pos))
return;
QList<QGraphicsItem *> &children = parent->d_ptr->children;
@@ -1527,31 +1612,73 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
continue;
// Skip invisible items and all their children.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0)))
+ if (item->d_ptr->isInvisible())
continue;
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
- QRectF mbr = item->mapRectToParent(br);
bool keep = false;
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Rect intersects/contains item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
- || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) {
+ if (!item->d_ptr->isClippedAway()) {
+ if (item->contains(item->mapFromParent(pos))) {
items->append(item);
keep = true;
}
- } else {
- // Rect intersects/contains item's shape
- if (QRectF_intersects(rect, mbr)) {
- if (path == QPainterPath())
- path.addRect(rect);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ }
+
+ if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty())
+ // Recurse into children.
+ childItems_helper(items, item, item->mapFromParent(pos));
+ }
+}
+
+
+void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
+ const QGraphicsItem *parent,
+ const QRectF &rect,
+ Qt::ItemSelectionMode mode) const
+{
+ bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
+ QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent));
+ if (r.isEmpty())
+ return;
+
+ QPainterPath path;
+ QList<QGraphicsItem *> &children = parent->d_ptr->children;
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *item = children.at(i);
+ if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ continue;
+
+ // Skip invisible items and all their children.
+ if (item->d_ptr->isInvisible())
+ continue;
+
+ bool keep = false;
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ const QRectF br(adjustedItemBoundingRect(item));
+ QRectF mbr = item->mapRectToParent(br);
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Rect intersects/contains item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
+ || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) {
items->append(item);
keep = true;
}
+ } else {
+ // Rect intersects/contains item's shape
+ if (QRectF_intersects(rect, mbr)) {
+ if (path == QPainterPath())
+ path.addRect(rect);
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
@@ -1568,18 +1695,22 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
}
}
+
void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
const QGraphicsItem *parent,
const QPolygonF &polygon,
Qt::ItemSelectionMode mode) const
{
- QPainterPath path;
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
- QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
+ QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
+ QPainterPath path;
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
@@ -1587,32 +1718,34 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
continue;
// Skip invisible items.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity() + 1, qreal(1.0)))
+ if (item->d_ptr->isInvisible())
continue;
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
bool keep = false;
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Polygon contains/intersects item's shape
- if (QRectF_intersects(polyRect, item->mapRectToParent(br))) {
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ const QRectF br(adjustedItemBoundingRect(item));
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
path.addPolygon(polygon);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
items->append(item);
keep = true;
}
+ } else {
+ // Polygon contains/intersects item's shape
+ if (QRectF_intersects(polyRect, item->mapRectToParent(br))) {
+ if (path == QPainterPath())
+ path.addPolygon(polygon);
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
@@ -1629,30 +1762,52 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
Qt::ItemSelectionMode mode) const
{
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- QPainterPath intersectedPath = !parentClip ? path : path.intersected(parent->shape());
- if (intersectedPath.isEmpty())
+ if (parentClip && parent->d_ptr->isClippedAway())
+ return;
+ QRectF pathRect(path.boundingRect());
+ _q_adjustRect(&pathRect);
+ QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent));
+ if (r.isEmpty())
return;
QList<QGraphicsItem *> &children = parent->d_ptr->children;
for (int i = 0; i < children.size(); ++i) {
QGraphicsItem *item = children.at(i);
+ if (item->d_ptr->hasTransform && !item->transform().isInvertible())
+ continue;
// Skip invisible items.
- if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0)))
+ if (item->d_ptr->isInvisible())
continue;
- QTransform x = item->sceneTransform();
-
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- QPainterPath mappedPath = xinv.map(path);
- if (itemCollidesWithPath(item, mappedPath, mode)) {
- items->append(item);
- if (!item->d_ptr->children.isEmpty())
- childItems_helper(items, item, mappedPath, mode);
+ bool keep = false;
+ if (!item->d_ptr->isClippedAway()) {
+ // ### _q_adjustedRect is only needed because QRectF::intersects,
+ // QRectF::contains and QTransform::map() and friends don't work with
+ // flat rectangles.
+ const QRectF br(adjustedItemBoundingRect(item));
+ if (mode >= Qt::ContainsItemBoundingRect) {
+ // Polygon contains/intersects item's bounding rect
+ if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
+ || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
+ items->append(item);
+ keep = true;
+ }
+ } else {
+ // Path contains/intersects item's shape
+ if (QRectF_intersects(pathRect, item->mapRectToParent(br))) {
+ if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
+ items->append(item);
+ keep = true;
+ }
+ }
}
}
+
+ if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
+ // Recurse into children that clip children.
+ childItems_helper(items, item, item->mapFromParent(path), mode);
+ }
}
}
@@ -2326,17 +2481,8 @@ QList<QGraphicsItem *> QGraphicsScene::items() const
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
{
- QList<QGraphicsItem *> itemsAtPoint;
-
- // Find all items within a 1x1 rect area starting at pos. This can be
- // inefficient for scenes that use small coordinates (like unity
- // coordinates), or for detailed graphs. ### The index should support
- // fetching items at a pos to avoid this limitation.
- foreach (QGraphicsItem *item, items(QRectF(pos, QSizeF(1, 1)), Qt::IntersectsItemBoundingRect)) {
- if (item->contains(item->mapFromScene(pos)))
- itemsAtPoint << item;
- }
- return itemsAtPoint;
+ Q_D(const QGraphicsScene);
+ return d->items_helper(pos);
}
@@ -2723,8 +2869,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Notify the item that its scene is changing, and allow the item to
// react.
- QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(this)));
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ qVariantFromValue<QGraphicsScene *>(this)));
+ QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
if (targetScene != this) {
if (targetScene && item->scene() != targetScene)
targetScene->addItem(item);
@@ -2818,7 +2965,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
emit selectionChanged();
// Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue<QGraphicsScene *>(this));
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
}
/*!
@@ -3082,8 +3229,9 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
// Notify the item that it's scene is changing to 0, allowing the item to
// react.
- QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(0)));
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ qVariantFromValue<QGraphicsScene *>(0)));
+ QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
if (targetScene != 0 && targetScene != this) {
targetScene->addItem(item);
return;
@@ -3154,6 +3302,16 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
d->unpolishedItems.removeAll(item);
d->dirtyItems.removeAll(item);
+ //We remove all references of item from the sceneEventFilter arrays
+ QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = d->sceneEventFilters.begin();
+ while (iterator != d->sceneEventFilters.end()) {
+ if (iterator.value() == item || iterator.key() == item)
+ iterator = d->sceneEventFilters.erase(iterator);
+ else
+ ++iterator;
+ }
+
+
//Ensure dirty flag have the correct default value so the next time it will be added it will receive updates
item->d_func()->dirty = 0;
item->d_func()->dirtyChildren = 0;
@@ -3181,7 +3339,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
emit selectionChanged();
// Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue<QGraphicsScene *>(0));
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
}
/*!
@@ -3455,7 +3613,7 @@ QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const
void QGraphicsScene::update(const QRectF &rect)
{
Q_D(QGraphicsScene);
- if (d->updateAll)
+ if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
return;
// Check if anyone's connected; if not, we can send updates directly to
@@ -4564,7 +4722,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Item's (local) bounding rect
QRectF brect = item->boundingRect();
- if (_q_adjustedRect(brect).isEmpty())
+ QRectF adjustedBrect(brect);
+ _q_adjustRect(&adjustedBrect);
+ if (adjustedBrect.isEmpty())
return;
// Fetch the off-screen transparent buffer and exposed area info.
@@ -4595,16 +4755,17 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
QSize pixmapSize;
bool fixedCacheSize = false;
+ QRectF brectAligned = brect.toAlignedRect();
if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
pixmapSize = itemCache->fixedSize;
} else {
- pixmapSize = brect.toAlignedRect().size();
+ pixmapSize = brectAligned.size().toSize();
}
// Create or recreate the pixmap.
int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
QSize adjustSize(adjust*2, adjust*2);
- QRectF br = brect.adjusted(-adjust, -adjust, adjust, adjust);
+ QRectF br = brectAligned.adjusted(-adjust, -adjust, adjust, adjust);
if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
pix = QPixmap(pixmapSize + adjustSize);
itemCache->exposed.clear();
@@ -4614,9 +4775,11 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Redraw any newly exposed areas.
if (itemCache->allExposed || !itemCache->exposed.isEmpty()) {
// Fit the item's bounding rect into the pixmap's coordinates.
- const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
QTransform itemToPixmap;
- itemToPixmap.scale(scale.x(), scale.y());
+ if (fixedCacheSize) {
+ const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
+ itemToPixmap.scale(scale.x(), scale.y());
+ }
itemToPixmap.translate(-br.x(), -br.y());
// Generate the item's exposedRect and map its list of expose
@@ -4733,11 +4896,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
QPoint diff = newCacheIndent - deviceData->cacheIndent;
QPixmap newPix(deviceRect.size());
- // ### Investigate removing this fill (test with Plasma and
- // graphicssystem raster).
- newPix.fill(Qt::transparent);
if (!pix.isNull()) {
QPainter newPixPainter(&newPix);
+ newPixPainter.setCompositionMode(QPainter::CompositionMode_Source);
newPixPainter.drawPixmap(-diff, pix);
newPixPainter.end();
}
@@ -4769,8 +4930,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
// Construct an item-to-pixmap transform.
QPointF p = deviceRect.topLeft();
- QTransform itemToPixmap = QTransform::fromTranslate(-p.x(), -p.y());
- itemToPixmap = painter->worldTransform() * itemToPixmap;
+ QTransform itemToPixmap = painter->worldTransform();
+ if (!p.isNull())
+ itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y());
// Map the item's logical expose to pixmap coordinates.
QRegion pixmapExposed = scrollExposure;
@@ -5104,9 +5266,12 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
update(item->sceneBoundingRect());
} else {
// ### Remove _q_adjustedRects().
- QRectF boundingRect = _q_adjustedRect(item->boundingRect());
- if (!rect.isNull())
- boundingRect &= _q_adjustedRect(rect);
+ QRectF boundingRect(adjustedItemBoundingRect(item));
+ if (!rect.isNull()) {
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
+ boundingRect &= adjustedRect;
+ }
// Update each view directly.
for (int i = 0; i < d->views.size(); ++i)
@@ -5118,6 +5283,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
d->resetDirtyItemsLater();
}
+ if (!item->isVisible())
+ return; // Hiding an item won't effect the largestUntransformableItem/sceneRect.
+
// Update d->largestUntransformableItem by mapping this item's bounding
// rect back to the topmost untransformable item's untransformed
// coordinate system (which sort of equals the 1:1 coordinate system of an
@@ -5133,7 +5301,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
// defined scene rect.
if (!d->hasSceneRect) {
QRectF oldGrowingItemsBoundingRect = d->growingItemsBoundingRect;
- d->growingItemsBoundingRect |= _q_adjustedRect(item->sceneBoundingRect());
+ QRectF adjustedItemSceneBoundingRect(item->sceneBoundingRect());
+ _q_adjustRect(&adjustedItemSceneBoundingRect);
+ d->growingItemsBoundingRect |= adjustedItemSceneBoundingRect;
if (d->growingItemsBoundingRect != oldGrowingItemsBoundingRect)
emit sceneRectChanged(d->growingItemsBoundingRect);
}
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 9c165d1..befbbd8 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -197,6 +197,7 @@ public:
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
+ QList<QGraphicsItem *> items_helper(const QPointF &pos) const;
QList<QGraphicsItem *> items_helper(const QRectF &rect,
Qt::ItemSelectionMode mode,
Qt::SortOrder order) const;
@@ -208,6 +209,9 @@ public:
Qt::SortOrder order) const;
void childItems_helper(QList<QGraphicsItem *> *items,
const QGraphicsItem *parent,
+ const QPointF &pos) const;
+ void childItems_helper(QList<QGraphicsItem *> *items,
+ const QGraphicsItem *parent,
const QRectF &rect,
Qt::ItemSelectionMode mode) const;
void childItems_helper(QList<QGraphicsItem *> *items,
diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp
index 57c79db..b819c2c 100644
--- a/src/gui/graphicsview/qgraphicssceneevent.cpp
+++ b/src/gui/graphicsview/qgraphicssceneevent.cpp
@@ -133,7 +133,7 @@
A QContextMenuEvent received by a QGraphicsView is translated
into a QGraphicsSceneContextMenuEvent. The
- QWheelEvent::globalPos() is translated into item, scene, and
+ QContextMenuEvent::globalPos() is translated into item, scene, and
screen coordinates (pos(), scenePos(), and screenPos()).
\sa QGraphicsSceneMouseEvent, QGraphicsSceneWheelEvent,
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 15c0e25..b5a1bdf 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -790,6 +790,19 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q
return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
}
+// QRectF::intersects() returns false always if either the source or target
+// rectangle's width or height are 0. This works around that problem.
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ if (!boundingRect.width())
+ boundingRect.adjust(-0.00001, 0, 0.00001, 0);
+ if (!boundingRect.height())
+ boundingRect.adjust(0, -0.00001, 0, 0.00001);
+ return boundingRect;
+}
+
/*!
\internal
*/
@@ -801,38 +814,37 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect)
updateLater();
QRectF updateRect = rect;
- if (item->isClipped()) {
+ if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) {
+ updateRect &= adjustedItemBoundingRect(item);
+ if (updateRect.isEmpty())
+ return;
+ }
+
+ QGraphicsItem *clipItem = item;
+ if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
// Minimize unnecessary redraw.
- QGraphicsItem *p = item;
- while ((p = p->d_ptr->parent)) {
- if (p->flags() & QGraphicsItem::ItemClipsChildrenToShape) {
- updateRect &= p->itemTransform(item).mapRect(p->boundingRect());
- if (updateRect.isNull())
+ QGraphicsItem *parent = item;
+ while ((parent = parent->d_ptr->parent)) {
+ if (parent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) {
+ // Map update rect to the current parent and itersect with its bounding rect.
+ updateRect = clipItem->itemTransform(parent).mapRect(updateRect)
+ & adjustedItemBoundingRect(parent);
+ if (updateRect.isEmpty())
return;
+ clipItem = parent;
}
- if (!(p->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
break;
}
-
- if (updateRect.isNull())
- return;
}
- // Map the rect to view coordinates.
- QRect vr = viewport->rect();
-
- if (!item->d_ptr->hasBoundingRegionGranularity) {
- QRect r = mapToViewRect(item, updateRect) & vr;
- if (r.isNull())
- return;
- this->updateRect(r);
- } else {
- QRegion r = mapToViewRegion(item, updateRect) & vr;
- if (r.isEmpty())
- return;
- updateRegion(r);
- }
+ // Map update rect from clipItem coordinates to view coordinates.
+ Q_ASSERT(clipItem);
+ if (!item->d_ptr->hasBoundingRegionGranularity)
+ this->updateRect(mapToViewRect(clipItem, updateRect) & viewport->rect());
+ else
+ updateRegion(mapToViewRegion(clipItem, updateRect) & viewport->rect());
}
void QGraphicsViewPrivate::updateLater()
@@ -855,16 +867,19 @@ void QGraphicsViewPrivate::_q_updateLaterSlot()
const QList<QGraphicsItem *> &dirtyItems = scene->d_func()->dirtyItems;
for (int i = 0; i < dirtyItems.size(); ++i) {
const QGraphicsItem *item = dirtyItems.at(i);
+ if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/false,
+ /*ignoreVisibleBit=*/false,
+ /*ignoreDirtyBit=*/true)) {
+ continue;
+ }
QTransform x = item->sceneTransform() * viewTransform;
- QRect viewRect = x.mapRect(item->boundingRect()).toAlignedRect() & vr;
- if (!viewRect.isNull())
- updateRect(viewRect);
+ updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr);
}
dirtyRectCount += dirtyRects.size();
bool noUpdate = !fullUpdatePending && viewportUpdateMode == QGraphicsView::FullViewportUpdate;
- if ((dirtyRectCount > 0 || !dirtyBoundingRect.isNull()) && !fullUpdatePending && !noUpdate) {
+ if ((dirtyRectCount > 0 || !dirtyBoundingRect.isEmpty()) && !fullUpdatePending && !noUpdate) {
if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate
|| (viewportUpdateMode == QGraphicsView::SmartViewportUpdate
&& dirtyRectCount >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD)) {
@@ -921,6 +936,9 @@ void QGraphicsViewPrivate::updateAll()
void QGraphicsViewPrivate::updateRegion(const QRegion &r)
{
+ if (r.isEmpty())
+ return;
+
Q_Q(QGraphicsView);
// Rect intersects viewport - update everything?
@@ -969,6 +987,9 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r)
void QGraphicsViewPrivate::updateRect(const QRect &r)
{
+ if (r.isEmpty())
+ return;
+
Q_Q(QGraphicsView);
// Rect intersects viewport - update everything?
@@ -1023,105 +1044,73 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array
delete [] array;
}
+extern QPainterPath qt_regionToPath(const QRegion &region);
-QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion,
- const QTransform &worldTransform,
- bool *allItems) const
+/*!
+ ### Adjustments in findItems: mapToScene(QRect) forces us to adjust the
+ input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight()
+ (etc) when mapping the rectangle to a polygon (which is _wrong_). In
+ addition, as QGraphicsItem::boundingRect() is defined in logical space,
+ but the default pen for QPainter is cosmetic with a width of 0, QPainter
+ is at risk of painting 1 pixel outside the bounding rect. Therefore we
+ must search for items with an adjustment of (-1, -1, 1, 1).
+*/
+QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const
{
Q_Q(const QGraphicsView);
- QList<QGraphicsItem *> itemList;
- QSet<QGraphicsItem *> tmp;
- bool simpleTransform = worldTransform.type() <= QTransform::TxScale;
-
- extern QPainterPath qt_regionToPath(const QRegion &region);
- QPainterPath path = qt_regionToPath(exposedRegion);
- *allItems = path.contains(q->mapFromScene(scene->d_func()->growingItemsBoundingRect).boundingRect());
- QList<QRectF> exposedRects;
- QList<QPolygonF> exposedPolys;
-
- // Transform the exposed viewport rects to scene rects or polygons
- foreach (const QRect &rect, exposedRegion.rects()) {
- QPolygonF exposedPoly = q->mapToScene(rect.adjusted(-1, -1, 1, 1));
- QRectF exposedRect = exposedPoly.boundingRect();
- if (!simpleTransform)
- exposedPolys << exposedPoly;
- exposedRects << exposedRect;
- }
-
- // Find which items need to be drawn.
- if (*allItems) {
+
+ // Step 1) If all items are contained within the expose region, then
+ // return a list of all visible items.
+ const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 2, 2))
+ .boundingRect();
+ if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) {
+ Q_ASSERT(allItems);
+ *allItems = true;
+
// All items are guaranteed within the exposed region, don't bother using the index.
- foreach (QGraphicsItem *item, scene->items()) {
+ QList<QGraphicsItem *> itemList(scene->items());
+ int i = 0;
+ while (i < itemList.size()) {
// But we only want to include items that are visible
- if (item->isVisible())
- itemList << item;
- }
- } else if (simpleTransform) {
- // Simple rect lookups will do.
- if (exposedRects.size() > 1) {
- foreach (const QRectF &rect, exposedRects) {
- foreach (QGraphicsItem *item, scene->d_func()->items_helper(rect, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) {
- if (!tmp.contains(item)) {
- tmp << item;
- itemList << item;
- }
- }
- }
- } else {
- itemList += scene->d_func()->items_helper(exposedRects[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */);
- }
- } else {
- // Polygon lookup is necessary.
- if (exposedRects.size() > 1) {
- foreach (const QPolygonF &poly, exposedPolys) {
- foreach (QGraphicsItem *item, scene->d_func()->items_helper(poly, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) {
- if (!tmp.contains(item)) {
- tmp << item;
- itemList << item;
- }
- }
- }
- } else {
- itemList += scene->d_func()->items_helper(exposedPolys[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */);
+ if (!itemList.at(i)->isVisible())
+ itemList.removeAt(i);
+ else
+ ++i;
}
+
+ // Sort the items.
+ QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled);
+ return itemList;
}
- // Check for items that ignore inherited transformations, and add them if
- // necessary.
- QRectF untr = scene->d_func()->largestUntransformableItem;
- if (!*allItems && !untr.isNull()) {
- // Map the largest untransformable item subtree boundingrect from view
- // to scene coordinates, and use this to expand all exposed rects in
- // search for untransformable items.
- QRectF ltri = matrix.inverted().mapRect(untr);
- ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height());
-
- foreach (const QRect &rect, exposedRegion.rects()) {
- QRectF exposed = q->mapToScene(rect.adjusted(-1, -1, 1, 1)).boundingRect();
- exposed.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height());
-
- foreach (QGraphicsItem *item, scene->d_func()->estimateItemsInRect(exposed)) {
- if (item->d_ptr->itemIsUntransformable()) {
- if (!tmp.contains(item)) {
- QPainterPath rectPath;
- rectPath.addRect(rect);
- QPainterPath path = item->deviceTransform(q->viewportTransform()).inverted().map(rectPath);
- if (item->collidesWithPath(path, Qt::IntersectsItemBoundingRect)) {
- itemList << item;
- tmp << item;
- }
- }
- }
- }
- }
+ // Step 2) If the expose region is a simple rect and the view is only
+ // translated or scaled, search for items using
+ // QGraphicsScene::items(QRectF).
+ bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull()
+ && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale);
+ if (simpleRectLookup) {
+ return scene->d_func()->items_helper(exposedRegionSceneBounds,
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder);
}
- tmp.clear();
- // Sort the items.
- QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder,
- scene->d_func()->sortCacheEnabled);
+ // If the region is complex or the view has a complex transform, adjust
+ // the expose region, convert it to a path, and then search for items
+ // using QGraphicsScene::items(QPainterPath);
+ QRegion adjustedRegion;
+ foreach (const QRect &r, exposedRegion.rects())
+ adjustedRegion += r.adjusted(-1, -1, 1, 1);
+
+ const QPainterPath exposedPath(qt_regionToPath(adjustedRegion));
+ if (scene->d_func()->largestUntransformableItem.isNull()) {
+ const QPainterPath exposedScenePath(q->mapToScene(exposedPath));
+ return scene->d_func()->items_helper(exposedScenePath,
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder);
+ }
- return itemList;
+ // NB! Path must be in viewport coordinates.
+ return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder);
}
void QGraphicsViewPrivate::generateStyleOptions(const QList<QGraphicsItem *> &itemList,
@@ -2224,7 +2213,8 @@ QList<QGraphicsItem *> QGraphicsView::items() const
certainly room for improvement.
*/
QList<QGraphicsItem *> QGraphicsViewPrivate::itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode) const
+ Qt::ItemSelectionMode mode,
+ Qt::SortOrder order) const
{
Q_Q(const QGraphicsView);
@@ -2274,8 +2264,8 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat
}
// ### Insertion sort would be faster.
- QGraphicsScenePrivate::sortItems(&result, Qt::AscendingOrder,
- scene->d_func()->sortCacheEnabled);
+ if (order != Qt::SortOrder(-1))
+ QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled);
return result;
}
@@ -3280,7 +3270,7 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
}
// Update old rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) {
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) {
if (d->viewportUpdateMode != FullViewportUpdate)
viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
else
@@ -3462,7 +3452,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
QPainter painter(viewport());
QTransform original = painter.worldTransform();
#ifndef QT_NO_RUBBERBAND
- if (d->rubberBanding && !d->rubberBandRect.isNull())
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty())
painter.save();
#endif
// Set up render hints
@@ -3481,7 +3471,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Find all exposed items
bool allItems = false;
- QList<QGraphicsItem *> itemList = d->findItems(exposedRegion, viewTransform, &allItems);
+ QList<QGraphicsItem *> itemList = d->findItems(exposedRegion, &allItems);
#ifdef QGRAPHICSVIEW_DEBUG
int exposedTime = stopWatch.elapsed();
@@ -3557,7 +3547,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
#ifndef QT_NO_RUBBERBAND
// Rubberband
- if (d->rubberBanding && !d->rubberBandRect.isNull()) {
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
painter.restore();
QStyleOptionRubberBand option;
option.initFrom(viewport());
@@ -3631,30 +3621,30 @@ void QGraphicsView::scrollContentsBy(int dx, int dy)
if (isRightToLeft())
dx = -dx;
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate
- && d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
- for (int i = 0; i < d->dirtyRects.size(); ++i)
- d->dirtyRects[i].translate(dx, dy);
- for (int i = 0; i < d->dirtyRegions.size(); ++i)
- d->dirtyRegions[i].translate(dx, dy);
- }
-
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
+ if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
+ for (int i = 0; i < d->dirtyRects.size(); ++i)
+ d->dirtyRects[i].translate(dx, dy);
+ for (int i = 0; i < d->dirtyRegions.size(); ++i)
+ d->dirtyRegions[i].translate(dx, dy);
+ if (d->accelerateScrolling) {
#ifndef QT_NO_RUBBERBAND
- // Update old rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) {
- if (d->viewportUpdateMode != FullViewportUpdate)
- viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
- else
- viewport()->update();
- }
+ // Update new and old rubberband regions
+ if (!d->rubberBandRect.isEmpty()) {
+ QRegion rubberBandRegion(d->rubberBandRegion(viewport(), d->rubberBandRect));
+ rubberBandRegion += rubberBandRegion.translated(-dx, -dy);
+ viewport()->update(rubberBandRegion);
+ }
#endif
-
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
- if (d->accelerateScrolling && d->viewportUpdateMode != FullViewportUpdate)
- viewport()->scroll(dx, dy);
- else
+ viewport()->scroll(dx, dy);
+ } else {
+ viewport()->update();
+ }
+ } else {
viewport()->update();
+ }
}
+
d->updateLastCenterPoint();
if ((d->cacheMode & CacheBackground)
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 2109673..a76279e 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -85,7 +85,8 @@ public:
qint64 verticalScroll() const;
QList<QGraphicsItem *> itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ Qt::ItemSelectionMode mode = Qt::IntersectsItemShape,
+ Qt::SortOrder = Qt::AscendingOrder) const;
QPointF mousePressItemPoint;
QPointF mousePressScenePoint;
@@ -172,9 +173,7 @@ public:
void updateRegion(const QRegion &region);
bool updateSceneSlotReimplementedChecked;
- QList<QGraphicsItem *> findItems(const QRegion &exposedRegion,
- const QTransform &worldTransform,
- bool *allItems) const;
+ QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems) const;
void generateStyleOptions(const QList<QGraphicsItem *> &itemList,
QGraphicsItem **itemArray,
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 5cc18f9..7f02fb9 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -366,32 +366,33 @@ void QGraphicsWidget::resize(const QSizeF &size)
void QGraphicsWidget::setGeometry(const QRectF &rect)
{
QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
- const QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr;
- setAttribute(Qt::WA_Resized);
- QRectF newGeom = rect;
- newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
- .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
- if (newGeom == d->geom)
- return;
-
- // Update and prepare to change the geometry (remove from index).
- if (wd->scene) {
- if (rect.topLeft() != d->geom.topLeft())
- wd->fullUpdateHelper(true);
- else
- update();
- }
- prepareGeometryChange();
-
- // setPos triggers ItemPositionChange, which can adjust position
+ QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr;
+ QRectF newGeom;
QPointF oldPos = d->geom.topLeft();
- wd->inSetGeometry = 1;
- wd->setPosHelper(newGeom.topLeft(), /* update = */ false);
- wd->inSetGeometry = 0;
- newGeom.moveTopLeft(pos());
-
- if (newGeom == d->geom)
- return;
+ if (!wd->inSetPos) {
+ setAttribute(Qt::WA_Resized);
+ newGeom = rect;
+ newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
+ .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
+ if (newGeom == d->geom)
+ return;
+
+ // setPos triggers ItemPositionChange, which can adjust position
+ wd->inSetGeometry = 1;
+ wd->setPosHelper(newGeom.topLeft());
+ wd->inSetGeometry = 0;
+ newGeom.moveTopLeft(pos());
+
+ if (newGeom == d->geom)
+ return;
+
+ // Update and prepare to change the geometry (remove from index) if the size has changed.
+ if (wd->scene) {
+ if (rect.topLeft() == d->geom.topLeft()) {
+ prepareGeometryChange();
+ }
+ }
+ }
// Update the layout item geometry
bool moved = oldPos != pos();
@@ -401,6 +402,11 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
event.setOldPos(oldPos);
event.setNewPos(pos());
QApplication::sendEvent(this, &event);
+ if (wd->inSetPos) {
+ //set the new pos
+ d->geom.moveTopLeft(pos());
+ return;
+ }
}
QSizeF oldSize = size();
QGraphicsLayoutItem::setGeometry(newGeom);
@@ -1016,9 +1022,11 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &
break;
case ItemPositionHasChanged:
if (!d->inSetGeometry) {
+ d->inSetPos = 1;
// Ensure setGeometry is called (avoid recursion when setPos is
// called from within setGeometry).
setGeometry(QRectF(pos(), size()));
+ d->inSetPos = 0 ;
}
break;
case ItemParentChange: {
@@ -1269,6 +1277,8 @@ bool QGraphicsWidget::event(QEvent *event)
break;
case QEvent::Polish:
polishEvent();
+ d->polished = true;
+ d->updateFont(d->font);
break;
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 641409d..789f8da 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -274,6 +274,8 @@ void QGraphicsWidgetPrivate::updateFont(const QFont &font)
}
}
+ if (!polished)
+ return;
// Notify change.
QEvent event(QEvent::FontChange);
QApplication::sendEvent(q, &event);
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
index afa6812..53eaa31 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ b/src/gui/graphicsview/qgraphicswidget_p.h
@@ -85,6 +85,8 @@ public:
inheritedPaletteResolveMask(0),
inheritedFontResolveMask(0),
inSetGeometry(0),
+ polished(0),
+ inSetPos(0),
focusPolicy(Qt::NoFocus),
focusNext(0),
focusPrev(0),
@@ -193,6 +195,8 @@ public:
}
quint32 attributes : 10;
quint32 inSetGeometry : 1;
+ quint32 polished: 1;
+ quint32 inSetPos : 1;
// Focus
Qt::FocusPolicy focusPolicy;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 558d574..c7a20db 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3607,6 +3607,9 @@ int QImage::pixelIndex(int x, int y) const
If the \a position is not valid, the results are undefined.
+ \warning This function is expensive when used for massive pixel
+ manipulations.
+
\sa setPixel(), valid(), {QImage#Pixel Manipulation}{Pixel
Manipulation}
*/
@@ -4937,10 +4940,12 @@ int QImage::dotsPerMeterY() const
meter, to \a x.
Together with dotsPerMeterY(), this number defines the intended
- scale and aspect ratio of the image.
+ scale and aspect ratio of the image, and determines the scale
+ at which QPainter will draw graphics on the image. It does not
+ change the scale or aspect ratio of the image when it is rendered
+ on other paint devices.
- \sa dotsPerMeterX(), {QImage#Image Information}{Image
- Information}
+ \sa dotsPerMeterX(), {QImage#Image Information}{Image Information}
*/
void QImage::setDotsPerMeterX(int x)
{
@@ -4957,10 +4962,12 @@ void QImage::setDotsPerMeterX(int x)
to \a y.
Together with dotsPerMeterX(), this number defines the intended
- scale and aspect ratio of the image.
+ scale and aspect ratio of the image, and determines the scale
+ at which QPainter will draw graphics on the image. It does not
+ change the scale or aspect ratio of the image when it is rendered
+ on other paint devices.
- \sa dotsPerMeterY(), {QImage#Image Information}{Image
- Information}
+ \sa dotsPerMeterY(), {QImage#Image Information}{Image Information}
*/
void QImage::setDotsPerMeterY(int y)
{
@@ -5577,6 +5584,8 @@ bool QImage::isDetached() const
Use one of the composition mods in QPainter::CompositionMode instead.
+ \warning This function is expensive.
+
\sa alphaChannel(), {QImage#Image Transformations}{Image
Transformations}, {QImage#Image Formats}{Image Formats}
*/
@@ -5659,6 +5668,11 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
\l{QPixmap::}{alphaChannel()}, which works in the same way as
this function on QPixmaps.
+ Most usecases for this function can be replaced with QPainter and
+ using composition modes.
+
+ \warning This is an expensive function.
+
\sa setAlphaChannel(), hasAlphaChannel(),
{QPixmap#Pixmap Information}{Pixmap},
{QImage#Image Transformations}{Image Transformations}
diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp
index 6b74323..33e565c 100644
--- a/src/gui/image/qnativeimage.cpp
+++ b/src/gui/image/qnativeimage.cpp
@@ -100,7 +100,9 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool is
bmi.blueMask = 0;
}
- hdc = CreateCompatibleDC(qt_win_display_dc());
+ HDC display_dc = GetDC(0);
+ hdc = CreateCompatibleDC(display_dc);
+ ReleaseDC(0, display_dc);
Q_ASSERT(hdc);
uchar *bits = 0;
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index cba9827..a130a1a 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -346,7 +346,7 @@ void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr)
if (corr) { // widen bounding rect
int w2 = painter()->pen().width() / 2;
br.setCoords(br.left() - w2, br.top() - w2,
- br.right() + w2, br.bottom() + w2);
+ br.right() + w2, br.bottom() + w2);
}
br = painter()->transform().mapRect(br);
if (painter()->hasClipping()) {
@@ -458,6 +458,25 @@ void QPicturePaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap
writeCmdLength(pos, r, false);
}
+void QPicturePaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QPicturePaintEngine);
+#ifdef QT_PICTURE_DEBUG
+ qDebug() << " -> drawImage():" << r << sr;
+#endif
+ int pos;
+ SERIALIZE_CMD(QPicturePrivate::PdcDrawImage);
+ if (d->pic_d->in_memory_only) {
+ int index = d->pic_d->image_list.size();
+ d->pic_d->image_list.append(image);
+ d->s << r << index << sr << (quint32) flags;
+ } else {
+ d->s << r << image << sr << (quint32) flags;
+ }
+ writeCmdLength(pos, r, false);
+}
+
extern int qt_defaultDpi();
void QPicturePaintEngine::drawTextItem(const QPointF &p , const QTextItem &ti)
diff --git a/src/gui/image/qpaintengine_pic_p.h b/src/gui/image/qpaintengine_pic_p.h
index 3ae0845..745d057 100644
--- a/src/gui/image/qpaintengine_pic_p.h
+++ b/src/gui/image/qpaintengine_pic_p.h
@@ -100,6 +100,8 @@ public:
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
+ Qt::ImageConversionFlags flags = Qt::AutoColor);
void drawTextItem(const QPointF &p, const QTextItem &ti);
Type type() const { return Picture; }
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index d5d7cb0..92023e0 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -759,13 +759,21 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords)
QImage image;
if (d->formatMajor < 4) {
s >> p >> image;
- painter->drawPixmap(p, QPixmap::fromImage(image));
+ painter->drawImage(p, image);
} else if (d->formatMajor <= 5){
s >> ir >> image;
- painter->drawPixmap(ir, QPixmap::fromImage(image), QRect(0, 0, ir.width(), ir.height()));
+ painter->drawImage(ir, image, QRect(0, 0, ir.width(), ir.height()));
} else {
- s >> r >> image;
- painter->drawPixmap(r, QPixmap::fromImage(image), QRectF(0, 0, r.width(), r.height()));
+ QRectF sr;
+ if (d->in_memory_only) {
+ int index;
+ s >> r >> index >> sr >> ul;
+ Q_ASSERT(index < d->image_list.size());
+ image = d->image_list.at(index);
+ } else {
+ s >> r >> image >> sr >> ul;
+ }
+ painter->drawImage(r, image, sr, Qt::ImageConversionFlags(ul));
}
}
break;
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index 1da7f07..a3fd34f 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -158,6 +158,7 @@ public:
QRect override_rect;
QPaintEngine *paintEngine;
bool in_memory_only;
+ QList<QImage> image_list;
QList<QPixmap> pixmap_list;
QList<QBrush> brush_list;
QList<QPen> pen_list;
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 8684a1b..efb8260 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -674,7 +674,7 @@ void QPixmap::resize_helper(const QSize &s)
pixels black. The effect of this function is undefined when the pixmap is
being painted on.
- This is potentially an expensive operation.
+ \warning This is potentially an expensive operation.
\sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
QBitmap
@@ -1380,6 +1380,12 @@ void QPixmap::deref()
If the given \a size is empty, this function returns a null
pixmap.
+
+ In some cases it can be more beneficial to draw the pixmap to a
+ painter with a scale set rather than scaling the pixmap. This is
+ the case when the painter is for instance based on OpenGL or when
+ the scale factor changes rapidly.
+
\sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
Transformations}
@@ -1751,6 +1757,10 @@ int QPixmap::metric(PaintDeviceMetric metric) const
The effect of this function is undefined when the pixmap is being
painted on.
+ \warning This is potentially an expensive operation. Most usecases
+ for this function are covered by QPainter and compositionModes
+ which will normally execute faster.
+
\sa alphaChannel(), {QPixmap#Pixmap Transformations}{Pixmap
Transformations}
*/
@@ -1793,6 +1803,9 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
\image alphachannelimage.png The pixmap and channelImage QPixmaps
+ \warning This is an expensive operation. The alpha channel of the
+ pixmap is extracted dynamically from the pixeldata.
+
\sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap
Information}
*/
@@ -1814,7 +1827,8 @@ QPaintEngine *QPixmap::paintEngine() const
Extracts a bitmap mask from the pixmap's alphachannel.
- This is potentially an expensive operation.
+ \warning This is potentially an expensive operation. The mask of
+ the pixmap is extracted dynamically from the pixeldata.
\sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
*/
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index bfc605b..26d9618 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -303,7 +303,7 @@ void QMacPixmapData::fromImage(const QImage &img,
else
one_bit = one_bit >> (x % 8);
if ((one_bit & 0x01))
- *(drow+x) = 0x00000000;
+ *(drow+x) = 0xFF000000;
else
*(drow+x) = 0xFFFFFFFF;
}
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index d758221..ff7c1b6 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -1288,6 +1288,12 @@ void QX11PixmapData::setMask(const QBitmap &newmask)
0, 0, 0, 0, 0, 0, w, h);
release();
*this = newData;
+ // the new QX11PixmapData object isn't referenced yet, so
+ // ref it
+ ref.ref();
+
+ // the below is to make sure the QX11PixmapData destructor
+ // doesn't delete our newly created render picture
newData.hd = 0;
newData.x11_mask = 0;
newData.picture = 0;
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 2e4da40..7296426 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -109,6 +109,7 @@ protected:
private:
friend class QPixmap;
friend class QGLContextPrivate;
+ friend class QX11PixmapData;
QAtomicInt ref;
int detach_no;
diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp
index 720f0b8..e3e8aa4 100644
--- a/src/gui/inputmethod/qwininputcontext_win.cpp
+++ b/src/gui/inputmethod/qwininputcontext_win.cpp
@@ -57,15 +57,17 @@
#ifdef Q_IME_DEBUG
#include "qdebug.h"
-#endif
-
-QT_BEGIN_NAMESPACE
+#endif
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
#if defined(Q_OS_WINCE)
extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp
#endif
+QT_BEGIN_NAMESPACE
+
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
+
+
DEFINE_GUID(IID_IActiveIMMApp,
0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e);
diff --git a/src/gui/inputmethod/qximinputcontext_p.h b/src/gui/inputmethod/qximinputcontext_p.h
index ca2103b..3773122 100644
--- a/src/gui/inputmethod/qximinputcontext_p.h
+++ b/src/gui/inputmethod/qximinputcontext_p.h
@@ -98,6 +98,7 @@ public:
QString text;
QBitArray selectedChars;
bool composing;
+ bool preeditEmpty;
void clear();
};
diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp
index 2fbe86f..c320fb4 100644
--- a/src/gui/inputmethod/qximinputcontext_x11.cpp
+++ b/src/gui/inputmethod/qximinputcontext_x11.cpp
@@ -264,6 +264,7 @@ extern "C" {
qic->standardFormat(QInputContext::PreeditFormat));
attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, sellen ? 0 : 1, QVariant());
QInputMethodEvent e(data->text, attrs);
+ data->preeditEmpty = data->text.isEmpty();
qic->sendEvent(e);
return 0;
@@ -286,11 +287,14 @@ void QXIMInputContext::ICData::clear()
text = QString();
selectedChars.clear();
composing = false;
+ preeditEmpty = true;
}
QXIMInputContext::ICData *QXIMInputContext::icData() const
{
- return ximData.value(focusWidget()->effectiveWinId());
+ if (QWidget *w = focusWidget())
+ return ximData.value(w->effectiveWinId());
+ return 0;
}
/* The cache here is needed, as X11 leaks a few kb for every
XFreeFontSet call, so we avoid creating and deletion of fontsets as
@@ -433,7 +437,8 @@ void QXIMInputContext::create_xim()
// reinitialize input context after the input method
// server (like SCIM) has been launched without
// requiring the user to manually switch focus.
- if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)
+ && focusWidget->testAttribute(Qt::WA_WState_Created))
setFocusWidget(focusWidget);
}
// following code fragment is not required for immodule
@@ -531,12 +536,14 @@ void QXIMInputContext::reset()
if (data->ic) {
char *mb = XmbResetIC(data->ic);
+ QInputMethodEvent e;
if (mb) {
- QInputMethodEvent e;
e.setCommitString(QString::fromLocal8Bit(mb));
- sendEvent(e);
XFree(mb);
-
+ data->preeditEmpty = false; // force sending an event
+ }
+ if (!data->preeditEmpty) {
+ sendEvent(e);
update();
}
}
@@ -562,12 +569,14 @@ void QXIMInputContext::mouseHandler(int pos, QMouseEvent *e)
return;
XIM_DEBUG("QXIMInputContext::mouseHandler pos=%d", pos);
- ICData *data = ximData.value(focusWidget()->effectiveWinId());
- if (!data)
- return;
- if (pos < 0 || pos > data->text.length())
- reset();
- // ##### handle mouse position
+ if (QWidget *w = focusWidget()) {
+ ICData *data = ximData.value(w->effectiveWinId());
+ if (!data)
+ return;
+ if (pos < 0 || pos > data->text.length())
+ reset();
+ // ##### handle mouse position
+ }
}
bool QXIMInputContext::isComposing() const
@@ -683,6 +692,7 @@ QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w)
{
ICData *data = new ICData;
data->widget = w;
+ data->preeditEmpty = true;
XVaNestedList preedit_attr = 0;
XIMCallback startcallback, drawcallback, donecallback;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index c7ba95d..55b3a03 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -1374,6 +1374,11 @@ bool QAbstractItemView::event(QEvent *event)
{
Q_D(QAbstractItemView);
switch (event->type()) {
+ case QEvent::Paint:
+ //we call this here because the scrollbars' visibility might be altered
+ //so this can't be done in the paintEvent method
+ d->executePostedLayout(); //make sure we set the layout properly
+ break;
case QEvent::Show:
{
d->executePostedLayout(); //make sure we set the layout properly
@@ -1395,6 +1400,9 @@ bool QAbstractItemView::event(QEvent *event)
case QEvent::FocusOut:
d->checkPersistentEditorFocus();
break;
+ case QEvent::FontChange:
+ d->doDelayedItemsLayout(); // the size of the items will change
+ break;
default:
break;
}
@@ -1501,12 +1509,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
// when the user is interacting with it (ie. clicking on it)
bool autoScroll = d->autoScroll;
d->autoScroll = false;
- // setSelection will update the current item too
- // and it seems that the two updates are not merged
- bool updates = d->viewport->updatesEnabled();
- d->viewport->setUpdatesEnabled(command == QItemSelectionModel::NoUpdate);
d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- d->viewport->setUpdatesEnabled(updates);
d->autoScroll = autoScroll;
QRect rect(d->pressedPosition - offset, pos);
setSelection(rect, command);
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 0aad6bb..bf9b5c5 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -291,6 +291,18 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
setModelData(), and updateEditorGeometry(). This process is
described in the \l{Spin Box Delegate Example}.
+ \section1 QStyledItemDelegate vs. QItemDelegate
+
+ Since Qt 4.4, there are two delegate classes: QItemDelegate and
+ QStyledItemDelegate. However, the default delegate is QStyledItemDelegate.
+ These two classes are independent alternatives to painting and providing
+ editors for items in views. The difference between them is that
+ QStyledItemDelegate uses the current style to paint its items. We therefore
+ recommend using QStyledItemDelegate as the base class when implementing
+ custom delegates or when working with Qt style sheets. The code required
+ for either class should be equal unless the custom delegate needs to use
+ the style for drawing.
+
\sa {Delegate Classes}, QStyledItemDelegate, QAbstractItemDelegate,
{Spin Box Delegate Example}, {Settings Editor Example},
{Icons Example}
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index d2fec21..07f0a38 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -2854,7 +2854,7 @@ void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
continue;
vi = &_this->dynamicListView->items[idx];
Q_ASSERT(vi);
- if (vi->rect().intersects(area) && vi->visited != visited) {
+ if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
QModelIndex index = _this->listViewItemToIndex(*vi);
Q_ASSERT(index.isValid());
_this->intersectVector.append(index);
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index b3993c7..91431c4 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -1032,9 +1032,21 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
}
}
- if (!source_rows_remove.isEmpty())
+ if (!source_rows_remove.isEmpty()) {
remove_source_items(m->proxy_rows, m->source_rows,
source_rows_remove, source_parent, Qt::Vertical);
+ QSet<int> source_rows_remove_set = source_rows_remove.toList().toSet();
+ QVector<QModelIndex>::iterator it = m->mapped_children.begin();
+ while (it != m->mapped_children.end()) {
+ const QModelIndex source_child_index = *it;
+ if (source_rows_remove_set.contains(source_child_index.row())) {
+ it = m->mapped_children.erase(it);
+ remove_from_mapping(source_child_index);
+ } else {
+ ++it;
+ }
+ }
+ }
if (!source_rows_resort.isEmpty()) {
// Re-sort the rows
@@ -1103,6 +1115,8 @@ void QSortFilterProxyModelPrivate::_q_sourceReset()
// All internal structures are deleted in clear()
q->reset();
update_source_sort_column();
+ if (dynamic_sortfilter)
+ sort();
}
void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged()
@@ -1495,6 +1509,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
d->clear_mapping();
reset();
+ d->update_source_sort_column();
}
/*!
@@ -1566,6 +1581,10 @@ bool QSortFilterProxyModel::hasChildren(const QModelIndex &parent) const
return false;
if (!d->model->hasChildren(source_parent))
return false;
+
+ if (d->model->canFetchMore(source_parent))
+ return true; //we assume we might have children that can be fetched
+
QSortFilterProxyModelPrivate::Mapping *m = d->create_mapping(source_parent).value();
return m->source_rows.count() != 0 && m->source_columns.count() != 0;
}
@@ -1893,7 +1912,7 @@ QSize QSortFilterProxyModel::span(const QModelIndex &index) const
void QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
{
Q_D(QSortFilterProxyModel);
- if (d->proxy_sort_column == column && d->sort_order == order)
+ if (d->dynamic_sortfilter && d->proxy_sort_column == column && d->sort_order == order)
return;
d->sort_order = order;
d->proxy_sort_column = column;
@@ -2107,6 +2126,8 @@ void QSortFilterProxyModel::setDynamicSortFilter(bool enable)
{
Q_D(QSortFilterProxyModel);
d->dynamic_sortfilter = enable;
+ if (enable)
+ d->sort();
}
/*!
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 271cc0d..be0971b 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -218,16 +218,17 @@ public:
The \l{Star Delegate Example}{Star Delegate} example creates
editors by reimplementing these methods.
- \section1 QStyledItemDelegate and QItemDelegate
-
- QStyledItemDelegate has taken over the job as default delegate -
- leaving QItemDelegate behind. They will now co-exist peacefully as
- independent alternatives to painting and providing editors for
- items in views. The difference between them is that the new
- delegate uses the current style to paint its items. We therefore
- recommend using QStyledItemDelegate as base when implementing
- custom delegates. The code required should be equal unless the
- custom delegate also wishes to use the style for drawing.
+ \section1 QStyledItemDelegate vs. QItemDelegate
+
+ Since Qt 4.4, there are two delegate classes: QItemDelegate and
+ QStyledItemDelegate. However, the default delegate is QStyledItemDelegate.
+ These two classes are independent alternatives to painting and providing
+ editors for items in views. The difference between them is that
+ QStyledItemDelegate uses the current style to paint its items. We therefore
+ recommend using QStyledItemDelegate as the base class when implementing
+ custom delegates or when working with Qt style sheets. The code required
+ for either class should be equal unless the custom delegate needs to use
+ the style for drawing.
If you wish to customize the painting of item views, you should
implement a custom style. Please see the QStyle class
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 34bb180..2902768 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -320,26 +320,12 @@ QRect QTableViewPrivate::visualSpanRect(const Span &span) const
\a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn
*/
void QTableViewPrivate::drawAndClipSpans(const QRect &area, QPainter *painter,
- const QStyleOptionViewItemV4 &option,
- QBitArray *drawn)
+ const QStyleOptionViewItemV4 &option, QBitArray *drawn,
+ int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)
{
bool alternateBase = false;
QRegion region = viewport->rect();
- int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
- int lastVisualRow = verticalHeader->visualIndexAt(viewport->height());
- if (lastVisualRow == -1)
- lastVisualRow = model->rowCount(root) - 1;
-
- int firstVisualColumn = horizontalHeader->visualIndexAt(0);
- int lastVisualColumn = horizontalHeader->visualIndexAt(viewport->width());
- if (q_func()->isRightToLeft())
- qSwap(firstVisualColumn, lastVisualColumn);
- if (firstVisualColumn == -1)
- firstVisualColumn = 0;
- if (lastVisualColumn == -1)
- lastVisualColumn = model->columnCount(root) - 1;
-
QList<Span>::const_iterator it;
for (it = spans.constBegin(); it != spans.constEnd(); ++it) {
Span span = *it;
@@ -768,10 +754,13 @@ void QTableView::paintEvent(QPaintEvent *event)
uint y = verticalHeader->length() - verticalHeader->offset() - 1;
QVector<QRect> rects = event->region().rects();
+
+ //firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
+ //same goes for ...VisualColumn
int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->viewport()->height());
if (lastVisualRow == -1)
- lastVisualRow = d->model->rowCount(d->root);
+ lastVisualRow = d->model->rowCount(d->root) - 1;
int firstVisualColumn = horizontalHeader->visualIndexAt(0);
int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->viewport()->width());
@@ -795,7 +784,8 @@ void QTableView::paintEvent(QPaintEvent *event)
}
if (d->hasSpans())
- d->drawAndClipSpans(dirtyArea, &painter, option, &drawn);
+ d->drawAndClipSpans(dirtyArea, &painter, option, &drawn,
+ firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
// get the horizontal start and end visual sections
int left = horizontalHeader->visualIndexAt(dirtyArea.left());
diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h
index a1c1152..b08eabd 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/gui/itemviews/qtableview_p.h
@@ -103,7 +103,8 @@ public:
bool spansIntersectColumns(const QList<int> &columns) const;
bool spansIntersectRows(const QList<int> &rows) const;
void drawAndClipSpans(const QRect &area, QPainter *painter,
- const QStyleOptionViewItemV4 &option, QBitArray *drawn);
+ const QStyleOptionViewItemV4 &option, QBitArray *drawn,
+ int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn);
void drawCell(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index);
bool showGrid;
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 943b194..62c1277 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -1239,16 +1239,23 @@ bool QTreeView::viewportEvent(QEvent *event)
int oldBranch = d->hoverBranch;
d->hoverBranch = d->itemDecorationAt(he->pos());
if (oldBranch != d->hoverBranch) {
- QRect oldRect = visualRect(d->modelIndex(oldBranch));
- QRect newRect = visualRect(d->modelIndex(d->hoverBranch));
- viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
- viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
+ QModelIndex oldIndex = d->modelIndex(oldBranch),
+ newIndex = d->modelIndex(d->hoverBranch);
+ if (oldIndex != newIndex) {
+ QRect oldRect = visualRect(oldIndex);
+ QRect newRect = visualRect(newIndex);
+ viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height());
+ viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height());
+ }
}
if (selectionBehavior() == QAbstractItemView::SelectRows) {
- QRect oldHoverRect = visualRect(d->hover);
- QRect newHoverRect = visualRect(indexAt(he->pos()));
- viewport()->update(QRect(0, newHoverRect.y(), viewport()->width(), newHoverRect.height()));
- viewport()->update(QRect(0, oldHoverRect.y(), viewport()->width(), oldHoverRect.height()));
+ QModelIndex newHoverIndex = indexAt(he->pos());
+ if (d->hover != newHoverIndex) {
+ QRect oldHoverRect = visualRect(d->hover);
+ QRect newHoverRect = visualRect(newHoverIndex);
+ viewport()->update(QRect(0, newHoverRect.y(), viewport()->width(), newHoverRect.height()));
+ viewport()->update(QRect(0, oldHoverRect.y(), viewport()->width(), oldHoverRect.height()));
+ }
}
break; }
default:
@@ -1377,7 +1384,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
// start at the top of the viewport and iterate down to the update area
for (; i < viewItems.count(); ++i) {
const int itemHeight = d->itemHeight(i);
- if (y + itemHeight >= area.top())
+ if (y + itemHeight > area.top())
break;
y += itemHeight;
}
@@ -2012,6 +2019,7 @@ int QTreeView::verticalOffset() const
// If we are scrolling per item and have non-uniform row heights,
// finding the vertical offset in pixels is going to be relatively slow.
// ### find a faster way to do this
+ d->executePostedLayout();
int offset = 0;
for (int i = 0; i < d->viewItems.count(); ++i) {
if (i == verticalScrollBar()->value())
@@ -2307,11 +2315,12 @@ void QTreeView::scrollContentsBy(int dx, int dy)
}
}
- if (d->viewItems.isEmpty() || d->defaultItemHeight == 0)
+ const int itemHeight = d->defaultItemHeight <= 0 ? sizeHintForRow(0) : d->defaultItemHeight;
+ if (d->viewItems.isEmpty() || itemHeight == 0)
return;
// guestimate the number of items in the viewport
- int viewCount = d->viewport->height() / d->defaultItemHeight;
+ int viewCount = d->viewport->height() / itemHeight;
int maxDeltaY = qMin(d->viewItems.count(), viewCount);
// no need to do a lot of work if we are going to redraw the whole thing anyway
if (qAbs(dy) > qAbs(maxDeltaY) && d->editors.isEmpty()) {
@@ -2558,8 +2567,11 @@ void QTreeView::sortByColumn(int column, Qt::SortOrder order)
{
Q_D(QTreeView);
- //will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts
+ //If sorting is enabled will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts
d->header->setSortIndicator(column, order);
+ //If sorting is not enabled, force to sort now.
+ if (!d->sortingEnabled)
+ d->model->sort(column, order);
}
/*!
@@ -3496,6 +3508,7 @@ void QTreeViewPrivate::updateScrollBars()
int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
{
+ const_cast<QTreeView *>(q_func())->executeDelayedItemsLayout();
int x = pos.x();
int column = header->logicalIndexAt(x);
if (column != 0)
diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp
index 357153d..6103225 100644
--- a/src/gui/itemviews/qtreewidget.cpp
+++ b/src/gui/itemviews/qtreewidget.cpp
@@ -2951,18 +2951,21 @@ QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const
/*!
\since 4.1
- Sets the given \a widget to be displayed in the cell specified by
- the given \a item and \a column.
-
- Note that the given \a widget's \l {QWidget}{autoFillBackground}
- property must be set to true, otherwise the widget's background will
- be transparent, showing both the model data and the tree widget
- item.
-
- This function should only be used to display static content in the
- place of a tree widget item. If you want to display custom dynamic
- content or implement a custom editor widget, use QTreeView and
- subclass QItemDelegate instead.
+ Sets the given \a widget to be displayed in the cell specified by the given
+ \a item and \a column.
+
+ The given \a widget's \l {QWidget::}{autoFillBackground} property must be
+ set to true, otherwise the widget's background will be transparent, showing
+ both the model data and the tree widget item.
+
+ This function should only be used to display static content in the place of
+ a tree widget item. If you want to display custom dynamic content or
+ implement a custom editor widget, use QTreeView and subclass QItemDelegate
+ instead.
+
+ This function cannot be called before the item hierarchy has been set up,
+ i.e., the QTreeWidgetItem that will hold \a widget must have been added to
+ the view before \a widget is set.
\note The tree takes ownership of the widget.
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 6971ed4..185fae2 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -169,189 +169,174 @@ QApplicationPrivate::~QApplicationPrivate()
}
/*!
- \class QApplication
- \brief The QApplication class manages the GUI application's control
- flow and main settings.
-
- \ingroup application
- \mainclass
-
- It contains the main event loop, where all events from the window
- system and other sources are processed and dispatched. It also
- handles the application's initialization and finalization, and
- provides session management. It also handles most system-wide and
- application-wide settings.
-
- For any GUI application that uses Qt, there is precisely one
- QApplication object, no matter whether the application has 0, 1, 2
- or more windows at any time. For non-GUI Qt applications, use
- QCoreApplication instead, which doesn't depend on the \l QtGui
- library.
-
- The QApplication object is accessible through the instance()
- function which return a pointer equivalent to the global qApp
- pointer.
-
- QApplication's main areas of responsibility are:
- \list
-
- \o It initializes the application with the user's desktop settings
- such as palette(), font() and doubleClickInterval(). It keeps track
- of these properties in case the user changes the desktop globally, for
- example through some kind of control panel.
-
- \o It performs event handling, meaning that it receives events
- from the underlying window system and dispatches them to the relevant
- widgets. By using sendEvent() and postEvent() you can send your own
- events to widgets.
-
- \o It parses common command line arguments and sets its internal
- state accordingly. See the \link QApplication::QApplication()
- constructor documentation\endlink below for more details about this.
-
- \o It defines the application's look and feel, which is
- encapsulated in a QStyle object. This can be changed at runtime
- with setStyle().
-
- \o It specifies how the application is to allocate colors.
- See setColorSpec() for details.
-
- \o It provides localization of strings that are visible to the user
- via translate().
-
- \o It provides some magical objects like the desktop() and the
- clipboard().
-
- \o It knows about the application's windows. You can ask which
- widget is at a certain position using widgetAt(), get a list of
- topLevelWidgets() and closeAllWindows(), etc.
-
- \o It manages the application's mouse cursor handling,
- see setOverrideCursor()
-
- \o On the X window system, it provides functions to flush and sync
- the communication stream, see flushX() and syncX().
-
- \o It provides support for sophisticated \link
- session.html session management \endlink. This makes it possible
- for applications to terminate gracefully when the user logs out, to
- cancel a shutdown process if termination isn't possible and even to
- preserve the entire application's state for a future session. See
- isSessionRestored(), sessionId() and commitData() and saveState()
- for details.
-
- \endlist
-
- Since the QApplication object does so much initialization, it
- \e{must} be created before any other objects related to the user
- interface are created.
-
- Since it also deals with common command line arguments, it is
- usually a good idea to create it \e before any interpretation or
- modification of \c argv is done in the application itself.
-
- \table
- \header \o{2,1} Groups of functions
- \row
- \o System settings
- \o
- desktopSettingsAware(),
- setDesktopSettingsAware(),
- cursorFlashTime(),
- setCursorFlashTime(),
- doubleClickInterval(),
- setDoubleClickInterval(),
- setKeyboardInputInterval(),
- wheelScrollLines(),
- setWheelScrollLines(),
- palette(),
- setPalette(),
- font(),
- setFont(),
- fontMetrics().
-
- \row
- \o Event handling
- \o
- exec(),
- processEvents(),
- exit(),
- quit().
- sendEvent(),
- postEvent(),
- sendPostedEvents(),
- removePostedEvents(),
- hasPendingEvents(),
- notify(),
- macEventFilter(),
- qwsEventFilter(),
- x11EventFilter(),
- x11ProcessEvent(),
- winEventFilter().
-
- \row
- \o GUI Styles
- \o
- style(),
- setStyle().
-
- \row
- \o Color usage
- \o
- colorSpec(),
- setColorSpec(),
- qwsSetCustomColors().
-
- \row
- \o Text handling
- \o
- installTranslator(),
- removeTranslator()
- translate().
-
- \row
- \o Widgets
- \o
- allWidgets(),
- topLevelWidgets(),
- desktop(),
- activePopupWidget(),
- activeModalWidget(),
- clipboard(),
- focusWidget(),
- winFocus(),
- activeWindow(),
- widgetAt().
-
- \row
- \o Advanced cursor handling
- \o
- overrideCursor(),
- setOverrideCursor(),
- restoreOverrideCursor().
-
- \row
- \o X Window System synchronization
- \o
- flushX(),
- syncX().
-
- \row
- \o Session management
- \o
- isSessionRestored(),
- sessionId(),
- commitData(),
- saveState().
-
- \row
- \o Miscellaneous
- \o
- closeAllWindows(),
- startingUp(),
- closingDown(),
- type().
- \endtable
+ \class QApplication
+ \brief The QApplication class manages the GUI application's control
+ flow and main settings.
+
+ \ingroup application
+ \mainclass
+
+ QApplication contains the main event loop, where all events from the window
+ system and other sources are processed and dispatched. It also handles the
+ application's initialization and finalization, and provides session
+ management. In addition, it handles most system-wide and application-wide
+ settings.
+
+ For any GUI application using Qt, there is precisely one QApplication
+ object, no matter whether the application has 0, 1, 2 or more windows at
+ any given time. For non-GUI Qt applications, use QCoreApplication instead,
+ as it does not depend on the \l QtGui library.
+
+ The QApplication object is accessible through the instance() function that
+ returns a pointer equivalent to the global qApp pointer.
+
+ QApplication's main areas of responsibility are:
+ \list
+ \o It initializes the application with the user's desktop settings
+ such as palette(), font() and doubleClickInterval(). It keeps
+ track of these properties in case the user changes the desktop
+ globally, for example through some kind of control panel.
+
+ \o It performs event handling, meaning that it receives events
+ from the underlying window system and dispatches them to the
+ relevant widgets. By using sendEvent() and postEvent() you can
+ send your own events to widgets.
+
+ \o It parses common command line arguments and sets its internal
+ state accordingly. See the \l{QApplication::QApplication()}
+ {constructor documentation} below for more details.
+
+ \o It defines the application's look and feel, which is
+ encapsulated in a QStyle object. This can be changed at runtime
+ with setStyle().
+
+ \o It specifies how the application is to allocate colors. See
+ setColorSpec() for details.
+
+ \o It provides localization of strings that are visible to the
+ user via translate().
+
+ \o It provides some magical objects like the desktop() and the
+ clipboard().
+
+ \o It knows about the application's windows. You can ask which
+ widget is at a certain position using widgetAt(), get a list of
+ topLevelWidgets() and closeAllWindows(), etc.
+
+ \o It manages the application's mouse cursor handling, see
+ setOverrideCursor()
+
+ \o On the X window system, it provides functions to flush and sync
+ the communication stream, see flushX() and syncX().
+
+ \o It provides support for sophisticated \l{Session Management}
+ {session management}. This makes it possible for applications
+ to terminate gracefully when the user logs out, to cancel a
+ shutdown process if termination isn't possible and even to
+ preserve the entire application's state for a future session.
+ See isSessionRestored(), sessionId() and commitData() and
+ saveState() for details.
+ \endlist
+
+ The QApplication object does so much initialization. Hence, it \e{must} be
+ created before any other objects related to the user interface are created.
+ Since QApplication also deals with common command line arguments, it is
+ usually a good idea to create it \e before any interpretation or
+ modification of \c argv is done in the application itself.
+
+ \table
+ \header
+ \o{2,1} Groups of functions
+
+ \row
+ \o System settings
+ \o desktopSettingsAware(),
+ setDesktopSettingsAware(),
+ cursorFlashTime(),
+ setCursorFlashTime(),
+ doubleClickInterval(),
+ setDoubleClickInterval(),
+ setKeyboardInputInterval(),
+ wheelScrollLines(),
+ setWheelScrollLines(),
+ palette(),
+ setPalette(),
+ font(),
+ setFont(),
+ fontMetrics().
+
+ \row
+ \o Event handling
+ \o exec(),
+ processEvents(),
+ exit(),
+ quit().
+ sendEvent(),
+ postEvent(),
+ sendPostedEvents(),
+ removePostedEvents(),
+ hasPendingEvents(),
+ notify(),
+ macEventFilter(),
+ qwsEventFilter(),
+ x11EventFilter(),
+ x11ProcessEvent(),
+ winEventFilter().
+
+ \row
+ \o GUI Styles
+ \o style(),
+ setStyle().
+
+ \row
+ \o Color usage
+ \o colorSpec(),
+ setColorSpec(),
+ qwsSetCustomColors().
+
+ \row
+ \o Text handling
+ \o installTranslator(),
+ removeTranslator()
+ translate().
+
+ \row
+ \o Widgets
+ \o allWidgets(),
+ topLevelWidgets(),
+ desktop(),
+ activePopupWidget(),
+ activeModalWidget(),
+ clipboard(),
+ focusWidget(),
+ activeWindow(),
+ widgetAt().
+
+ \row
+ \o Advanced cursor handling
+ \o overrideCursor(),
+ setOverrideCursor(),
+ restoreOverrideCursor().
+
+ \row
+ \o X Window System synchronization
+ \o flushX(),
+ syncX().
+
+ \row
+ \o Session management
+ \o isSessionRestored(),
+ sessionId(),
+ commitData(),
+ saveState().
+
+ \row
+ \o Miscellaneous
+ \o closeAllWindows(),
+ startingUp(),
+ closingDown(),
+ type().
+ \endtable
\sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings
*/
@@ -382,6 +367,7 @@ QApplicationPrivate::~QApplicationPrivate()
Returns the top-level widget at the given \a point; returns 0 if
there is no such widget.
*/
+
/*!
\fn QWidget *QApplication::topLevelAt(int x, int y)
@@ -393,8 +379,8 @@ QApplicationPrivate::~QApplicationPrivate()
/*
- The qt_init() and qt_cleanup() functions are implemented in the
- qapplication_xyz.cpp file.
+ The qt_init() and qt_cleanup() functions are implemented in the
+ qapplication_xyz.cpp file.
*/
void qt_init(QApplicationPrivate *priv, int type
@@ -580,99 +566,100 @@ void QApplicationPrivate::process_cmdline()
}
/*!
- Initializes the window system and constructs an application object
- with \a argc command line arguments in \a argv.
-
- \warning The data referred to by \a argc and \a argv must stay valid
- for the entire lifetime of the QApplication object. In addition,
- \a argc must be greater than zero and \a argv must contain at least
- one valid character string.
-
- The global \c qApp pointer refers to this application object. Only
- one application object should be created.
-
- This application object must be constructed before any \link
- QPaintDevice paint devices\endlink (including widgets, pixmaps, bitmaps
- etc.).
-
- Note that \a argc and \a argv might be changed. Qt removes command
- line arguments that it recognizes.
-
- Qt debugging options (not available if Qt was compiled without the
- QT_DEBUG flag defined):
- \list
- \o -nograb, tells Qt that it must never grab the mouse or the keyboard.
- \o -dograb (only under X11), running under a debugger can cause
- an implicit -nograb, use -dograb to override.
- \o -sync (only under X11), switches to synchronous mode for
- debugging.
- \endlist
-
- See \link debug.html Debugging Techniques \endlink for a more
- detailed explanation.
-
- All Qt programs automatically support the following command line options:
- \list
- \o -style= \e style, sets the application GUI style. Possible values
- are \c motif, \c windows, and \c platinum. If you compiled Qt
- with additional styles or have additional styles as plugins these
- will be available to the \c -style command line option.
- \o -style \e style, is the same as listed above.
- \o -stylesheet= \e stylesheet, sets the application \l styleSheet. The value
- must be a path to a file that contains the Style Sheet. Note that relative URLs
- in the Style Sheet file are relative to the Style Sheet file's path.
- \o -stylesheet \e stylesheet, is the same as listed above.
- \o -session= \e session, restores the application from an earlier
- \link session.html session \endlink.
- \o -session \e session, is the same as listed above.
- \o -widgetcount, prints debug message at the end about number of widgets left
- undestroyed and maximum number of widgets existed at the same time
- \o -reverse, sets the application's layout direction to Qt::RightToLeft
- \o -graphicssystem, sets the backend to be used for on-screen
- widgets and QPixmaps. Available options are \c{raster} and \c{opengl}.
-
- \endlist
-
- The Windows version of Qt also support one additional command line
- option, if Direct3D support has been compiled into Qt:
- \list
- \o -direct3d will make the Direct3D paint engine the default widget
- paint engine in Qt. \bold {This functionality is experimental.}
- \endlist
-
- The X11 version of Qt also supports some traditional X11
- command line options:
- \list
- \o -display \e display, sets the X display (default is $DISPLAY).
- \o -geometry \e geometry, sets the client geometry of the
- first window that is shown.
- \o -fn or \c -font \e font, defines the application font. The
- font should be specified using an X logical font description.
- \o -bg or \c -background \e color, sets the default background color
- and an application palette (light and dark shades are calculated).
- \o -fg or \c -foreground \e color, sets the default foreground color.
- \o -btn or \c -button \e color, sets the default button color.
- \o -name \e name, sets the application name.
- \o -title \e title, sets the application title.
- \o -visual \c TrueColor, forces the application to use a TrueColor visual
- on an 8-bit display.
- \o -ncols \e count, limits the number of colors allocated in the
- color cube on an 8-bit display, if the application is using the
- QApplication::ManyColor color specification. If \e count is
- 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
- and 6 of blue); for other values, a cube
- approximately proportional to a 2x3x1 cube is used.
- \o -cmap, causes the application to install a private color map
- on an 8-bit display.
- \o -im, sets the input method server (equivalent to setting the XMODIFIERS
- environment variable)
- \o -inputstyle, defines how the input is inserted into the given widget. E.g.,
- \c onTheSpot makes the input appear directly in the widget, while
- \c overTheSpot makes the input appear in a box floating over the
- widget and is not inserted until the editing is done.
- \endlist
-
- \sa arguments()
+ Initializes the window system and constructs an application object with
+ \a argc command line arguments in \a argv.
+
+ \warning The data referred to by \a argc and \a argv must stay valid for
+ the entire lifetime of the QApplication object. In addition, \a argc must
+ be greater than zero and \a argv must contain at least one valid character
+ string.
+
+ The global \c qApp pointer refers to this application object. Only one
+ application object should be created.
+
+ This application object must be constructed before any \l{QPaintDevice}
+ {paint devices} (including widgets, pixmaps, bitmaps etc.).
+
+ \note \a argc and \a argv might be changed as Qt removes command line
+ arguments that it recognizes.
+
+ Qt debugging options (not available if Qt was compiled without the QT_DEBUG
+ flag defined):
+ \list
+ \o -nograb, tells Qt that it must never grab the mouse or the
+ keyboard.
+ \o -dograb (only under X11), running under a debugger can cause an
+ implicit -nograb, use -dograb to override.
+ \o -sync (only under X11), switches to synchronous mode for
+ debugging.
+ \endlist
+
+ See \l{Debugging Techniques} for a more detailed explanation.
+
+ All Qt programs automatically support the following command line options:
+ \list
+ \o -style= \e style, sets the application GUI style. Possible values
+ are \c motif, \c windows, and \c platinum. If you compiled Qt with
+ additional styles or have additional styles as plugins these will
+ be available to the \c -style command line option.
+ \o -style \e style, is the same as listed above.
+ \o -stylesheet= \e stylesheet, sets the application \l styleSheet. The
+ value must be a path to a file that contains the Style Sheet.
+ \note Relative URLs in the Style Sheet file are relative to the
+ Style Sheet file's path.
+ \o -stylesheet \e stylesheet, is the same as listed above.
+ \o -session= \e session, restores the application from an earlier
+ \l{Session Management}{session}.
+ \o -session \e session, is the same as listed above.
+ \o -widgetcount, prints debug message at the end about number of
+ widgets left undestroyed and maximum number of widgets existed at
+ the same time
+ \o -reverse, sets the application's layout direction to
+ Qt::RightToLeft
+ \o -graphicssystem, sets the backend to be used for on-screen widgets
+ and QPixmaps. Available options are \c{raster} and \c{opengl}.
+ \endlist
+
+ The Windows version of Qt supports an additional command line option, if
+ Direct3D support has been compiled into Qt:
+ \list
+ \o -direct3d will make the Direct3D paint engine the default widget
+ paint engine in Qt. \bold {This functionality is experimental.}
+ \endlist
+
+ The X11 version of Qt supports some traditional X11 command line options:
+ \list
+ \o -display \e display, sets the X display (default is $DISPLAY).
+ \o -geometry \e geometry, sets the client geometry of the first window
+ that is shown.
+ \o -fn or \c -font \e font, defines the application font. The font
+ should be specified using an X logical font description.
+ \o -bg or \c -background \e color, sets the default background color
+ and an application palette (light and dark shades are calculated).
+ \o -fg or \c -foreground \e color, sets the default foreground color.
+ \o -btn or \c -button \e color, sets the default button color.
+ \o -name \e name, sets the application name.
+ \o -title \e title, sets the application title.
+ \o -visual \c TrueColor, forces the application to use a TrueColor
+ visual on an 8-bit display.
+ \o -ncols \e count, limits the number of colors allocated in the color
+ cube on an 8-bit display, if the application is using the
+ QApplication::ManyColor color specification. If \e count is 216
+ then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
+ and 6 of blue); for other values, a cube approximately proportional
+ to a 2x3x1 cube is used.
+ \o -cmap, causes the application to install a private color map on an
+ 8-bit display.
+ \o -im, sets the input method server (equivalent to setting the
+ XMODIFIERS environment variable)
+ \o -inputstyle, defines how the input is inserted into the given
+ widget, e.g., \c onTheSpot makes the input appear directly in the
+ widget, while \c overTheSpot makes the input appear in a box
+ floating over the widget and is not inserted until the editing is
+ done.
+ \endlist
+
+ \sa arguments()
*/
QApplication::QApplication(int &argc, char **argv)
@@ -685,26 +672,26 @@ QApplication::QApplication(int &argc, char **argv, int _internal)
/*!
- Constructs an application object with \a argc command line arguments
- in \a argv. If \a GUIenabled is true, a GUI application is
- constructed, otherwise a non-GUI (console) application is created.
+ Constructs an application object with \a argc command line arguments in
+ \a argv. If \a GUIenabled is true, a GUI application is constructed,
+ otherwise a non-GUI (console) application is created.
- \warning The data referred to by \a argc and \a argv must stay valid
- for the entire lifetime of the QApplication object. In addition,
- \a argc must be greater than zero and \a argv must contain at least
- one valid character string.
+ \warning The data referred to by \a argc and \a argv must stay valid for
+ the entire lifetime of the QApplication object. In addition, \a argc must
+ be greater than zero and \a argv must contain at least one valid character
+ string.
- Set \a GUIenabled to false for programs without a graphical user
- interface that should be able to run without a window system.
+ Set \a GUIenabled to false for programs without a graphical user interface
+ that should be able to run without a window system.
- On X11, the window system is initialized if \a GUIenabled is true.
- If \a GUIenabled is false, the application does not connect to the
- X server. On Windows and Macintosh, currently the window system is
- always initialized, regardless of the value of GUIenabled. This may
- change in future versions of Qt.
+ On X11, the window system is initialized if \a GUIenabled is true. If
+ \a GUIenabled is false, the application does not connect to the X server.
+ On Windows and Macintosh, currently the window system is always
+ initialized, regardless of the value of GUIenabled. This may change in
+ future versions of Qt.
- The following example shows how to create an application that
- uses a graphical interface when available.
+ The following example shows how to create an application that uses a
+ graphical interface when available.
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 0
*/
@@ -720,17 +707,17 @@ QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _intern
/*!
- Constructs an application object with \a argc command line arguments
- in \a argv.
+ Constructs an application object with \a argc command line arguments in
+ \a argv.
- \warning The data referred to by \a argc and \a argv must stay valid
- for the entire lifetime of the QApplication object. In addition,
- \a argc must be greater than zero and \a argv must contain at least
- one valid character string.
+ \warning The data referred to by \a argc and \a argv must stay valid for
+ the entire lifetime of the QApplication object. In addition, \a argc must
+ be greater than zero and \a argv must contain at least one valid character
+ string.
- With Qt for Embedded Linux, passing QApplication::GuiServer for \a type
- makes this application the server (equivalent to running with the
- \c -qws option).
+ With Qt for Embedded Linux, passing QApplication::GuiServer for \a type
+ makes this application the server (equivalent to running with the
+ \c -qws option).
*/
QApplication::QApplication(int &argc, char **argv, Type type)
: QCoreApplication(*new QApplicationPrivate(argc, argv, type))
@@ -778,16 +765,16 @@ static int aargc = 1;
static char *aargv[] = { (char*)"unknown", 0 };
/*!
- \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
+ \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
- Create an application, given an already open display \a display. If \a
- visual and \a colormap are non-zero, the application will use those as
- the default Visual and Colormap contexts.
+ Creates an application, given an already open display \a display. If
+ \a visual and \a colormap are non-zero, the application will use those
+ values as the default Visual and Colormap contexts.
- \warning Qt only supports TrueColor visuals at depths higher than 8
- bits-per-pixel.
+ \warning Qt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
- This is available only on X11.
+ This function is only available on X11.
*/
QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
: QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient))
@@ -809,19 +796,18 @@ QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
}
/*!
- \fn QApplication::QApplication(Display *display, int &argc, char **argv,
- Qt::HANDLE visual, Qt::HANDLE colormap)
+ \fn QApplication::QApplication(Display *display, int &argc, char **argv,
+ Qt::HANDLE visual, Qt::HANDLE colormap)
- Create an application, given an already open \a display and using \a
- argc command line arguments in \a argv. If \a visual and \a colormap
- are non-zero, the application will use those as the default Visual
- and Colormap contexts.
+ Creates an application, given an already open \a display and using \a argc
+ command line arguments in \a argv. If \a visual and \a colormap are
+ non-zero, the application will use those values as the default Visual
+ and Colormap contexts.
- \warning Qt only supports TrueColor visuals at depths higher than 8
- bits-per-pixel.
-
- This is available only on X11.
+ \warning Qt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
+ This function is only available on X11.
*/
QApplication::QApplication(Display *dpy, int &argc, char **argv,
Qt::HANDLE visual, Qt::HANDLE colormap)
@@ -850,6 +836,7 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv,
/*!
Initializes the QApplication object, called from the constructors.
*/
+extern void qInitDrawhelperAsm();
void QApplicationPrivate::initialize()
{
@@ -893,7 +880,6 @@ void QApplicationPrivate::initialize()
#endif //Q_OS_WINCE
// Set up which span functions should be used in raster engine...
- extern void qInitDrawhelperAsm();
qInitDrawhelperAsm();
#if !defined(Q_WS_X11) && !defined(Q_WS_QWS)
@@ -926,19 +912,18 @@ QApplication::Type QApplication::type()
*****************************************************************************/
/*!
- Returns the active popup widget.
+ Returns the active popup widget.
- A popup widget is a special top-level widget that sets the \c
- Qt::WType_Popup widget flag, e.g. the QMenu widget. When the
- application opens a popup widget, all events are sent to the popup.
- Normal widgets and modal widgets cannot be accessed before the popup
- widget is closed.
+ A popup widget is a special top-level widget that sets the \c
+ Qt::WType_Popup widget flag, e.g. the QMenu widget. When the application
+ opens a popup widget, all events are sent to the popup. Normal widgets and
+ modal widgets cannot be accessed before the popup widget is closed.
- Only other popup widgets may be opened when a popup widget is shown.
- The popup widgets are organized in a stack. This function returns
- the active popup widget at the top of the stack.
+ Only other popup widgets may be opened when a popup widget is shown. The
+ popup widgets are organized in a stack. This function returns the active
+ popup widget at the top of the stack.
- \sa activeModalWidget(), topLevelWidgets()
+ \sa activeModalWidget(), topLevelWidgets()
*/
QWidget *QApplication::activePopupWidget()
@@ -949,17 +934,17 @@ QWidget *QApplication::activePopupWidget()
/*!
- Returns the active modal widget.
+ Returns the active modal widget.
- A modal widget is a special top-level widget which is a subclass of
- QDialog that specifies the modal parameter of the constructor as
- true. A modal widget must be closed before the user can continue
- with other parts of the program.
+ A modal widget is a special top-level widget which is a subclass of QDialog
+ that specifies the modal parameter of the constructor as true. A modal
+ widget must be closed before the user can continue with other parts of the
+ program.
- Modal widgets are organized in a stack. This function returns
- the active modal widget at the top of the stack.
+ Modal widgets are organized in a stack. This function returns the active
+ modal widget at the top of the stack.
- \sa activePopupWidget(), topLevelWidgets()
+ \sa activePopupWidget(), topLevelWidgets()
*/
QWidget *QApplication::activeModalWidget()
@@ -968,8 +953,8 @@ QWidget *QApplication::activeModalWidget()
}
/*!
- Cleans up any window system resources that were allocated by this
- application. Sets the global variable \c qApp to 0.
+ Cleans up any window system resources that were allocated by this
+ application. Sets the global variable \c qApp to 0.
*/
QApplication::~QApplication()
@@ -1098,8 +1083,8 @@ QApplication::~QApplication()
/*!
\fn QWidget *QApplication::widgetAt(const QPoint &point)
- Returns the widget at global screen position \a point, or 0 if there
- is no Qt widget there.
+ Returns the widget at global screen position \a point, or 0 if there is no
+ Qt widget there.
This function can be slow.
@@ -1147,8 +1132,8 @@ QWidget *QApplication::widgetAt(const QPoint &p)
\overload
- Returns the widget at global screen position (\a x, \a y), or 0
- if there is no Qt widget there.
+ Returns the widget at global screen position (\a x, \a y), or 0 if there is
+ no Qt widget there.
*/
/*!
@@ -1217,16 +1202,17 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
\since 4.4
\brief defines a threshold for auto maximizing widgets
- The auto maximize threshold is only available
- as part of Qt for Windows CE.
+ The auto maximize threshold is only available as part of Qt for Windows CE.
This property defines a threshold for the size of a window as a percentage
- of the screen size. If the minimum size hint of a window exceeds the threshold,
- calling show() will then cause the window to be maximized automatically.
+ of the screen size. If the minimum size hint of a window exceeds the
+ threshold, calling show() will then cause the window to be maximized
+ automatically.
- Setting the threshold to be 100 or greater means that it will cause it to always
- be maximized. Setting it to be 50 means that the widget is maximized if the vertical
- minimum size hint is at least 50% of the vertical screen size.
+ Setting the threshold to be 100 or greater means that it will cause it to
+ always be maximized. Setting it to be 50 means that the widget is maximized
+ if the vertical minimum size hint is at least 50% of the vertical screen
+ size.
If -1 is specified then this will disable the feature.
@@ -1239,12 +1225,11 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
\since 4.5
\brief toggles automatic SIP (software input panel) visibility
- The auto SIP property is only available
- as part of Qt for Windows CE.
+ The auto SIP property is only available as part of Qt for Windows CE.
Set this property to true to automatically display the SIP when entering
- widgets that accept keyboard input. This only affects widgets that have the
- attribute WA_InputMethodEnabled set.
+ widgets that accept keyboard input. This property only affects widgets with
+ the WA_InputMethodEnabled attribute set.
*/
#ifdef Q_OS_WINCE
@@ -1296,9 +1281,9 @@ void QApplication::setStyleSheet(const QString& styleSheet)
#endif // QT_NO_STYLE_STYLESHEET
/*!
- Returns the application's style object.
+ Returns the application's style object.
- \sa setStyle(), QStyle
+ \sa setStyle(), QStyle
*/
QStyle *QApplication::style()
{
@@ -1381,22 +1366,21 @@ QStyle *QApplication::style()
}
/*!
- Sets the application's GUI style to \a style. Ownership of the style
- object is transferred to QApplication, so QApplication will delete
- the style object on application exit or when a new style is set and
- the old style is still the parent of the application object.
+ Sets the application's GUI style to \a style. Ownership of the style object
+ is transferred to QApplication, so QApplication will delete the style
+ object on application exit or when a new style is set and the old style is
+ still the parent of the application object.
Example usage:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 1
- When switching application styles, the color palette is set back to
- the initial colors or the system defaults. This is necessary since
- certain styles have to adapt the color palette to be fully
- style-guide compliant.
+ When switching application styles, the color palette is set back to the
+ initial colors or the system defaults. This is necessary since certain
+ styles have to adapt the color palette to be fully style-guide compliant.
- Note that setting the style before a palette has been set
- (i.e. before creating QApplication) will cause the application to
- use QStyle::standardPalette() for the palette.
+ Setting the style before a palette has been se, i.e., before creating
+ QApplication, will cause the application to use QStyle::standardPalette()
+ for the palette.
\warning Qt style sheets are currently not supported for custom QStyle
subclasses. We plan to address this in some future release.
@@ -1499,20 +1483,20 @@ void QApplication::setStyle(QStyle *style)
}
/*!
- \overload
+ \overload
- Requests a QStyle object for \a style from the QStyleFactory.
+ Requests a QStyle object for \a style from the QStyleFactory.
- The string must be one of the QStyleFactory::keys(), typically one
- of "windows", "motif", "cde", "plastique", "windowsxp", or
- "macintosh". Style names are case insensitive.
+ The string must be one of the QStyleFactory::keys(), typically one of
+ "windows", "motif", "cde", "plastique", "windowsxp", or "macintosh". Style
+ names are case insensitive.
- Returns 0 if an unknown \a style is passed, otherwise the QStyle object
- returned is set as the application's GUI style.
+ Returns 0 if an unknown \a style is passed, otherwise the QStyle object
+ returned is set as the application's GUI style.
- \warning To ensure that the application's style is set correctly, it is
- best to call this function before the QApplication constructor, if
- possible.
+ \warning To ensure that the application's style is set correctly, it is
+ best to call this function before the QApplication constructor, if
+ possible.
*/
QStyle* QApplication::setStyle(const QString& style)
{
@@ -1525,20 +1509,19 @@ QStyle* QApplication::setStyle(const QString& style)
}
/*!
- \since 4.5
+ \since 4.5
- Sets the default graphics backend to \a system, which will be used
- for on-screen widgets and QPixmaps. The available systems are
- \c{"native"}, \c{"raster"} and \c{"opengl"}.
+ Sets the default graphics backend to \a system, which will be used for
+ on-screen widgets and QPixmaps. The available systems are \c{"native"},
+ \c{"raster"} and \c{"opengl"}.
- Note that this function call overrides both the application
- commandline \c{-graphicssystem} switch and the configure
- \c{-graphicssystem} switch.
+ This function call overrides both the application commandline
+ \c{-graphicssystem} switch and the configure \c{-graphicssystem} switch.
- \warning This function must be called before the QApplication
- constructor is called.
+ \warning This function must be called before the QApplication constructor
+ is called.
- The \c{"opengl"} option is currently considered experimental.
+ \note The \c{"opengl"} option is currently experimental.
*/
void QApplication::setGraphicsSystem(const QString &system)
@@ -1547,9 +1530,10 @@ void QApplication::setGraphicsSystem(const QString &system)
}
/*!
- Returns the color specification.
- \sa QApplication::setColorSpec()
- */
+ Returns the color specification.
+
+ \sa QApplication::setColorSpec()
+*/
int QApplication::colorSpec()
{
@@ -1557,54 +1541,54 @@ int QApplication::colorSpec()
}
/*!
- Sets the color specification for the application to \a spec.
-
- The color specification controls how the application allocates colors
- when run on a display with a limited amount of colors, e.g. 8 bit / 256
- color displays.
-
- The color specification must be set before you create the QApplication
- object.
-
- The options are:
- \list
- \o QApplication::NormalColor.
- This is the default color allocation strategy. Use this option if
- your application uses buttons, menus, texts and pixmaps with few
- colors. With this option, the application uses system global
- colors. This works fine for most applications under X11, but on
- Windows machines it may cause dithering of non-standard colors.
- \o QApplication::CustomColor.
- Use this option if your application needs a small number of custom
- colors. On X11, this option is the same as NormalColor. On Windows, Qt
- creates a Windows palette, and allocates colors to it on demand.
- \o QApplication::ManyColor.
- Use this option if your application is very color hungry
- (e.g. it requires thousands of colors).
- Under X11 the effect is:
+ Sets the color specification for the application to \a spec.
+
+ The color specification controls how the application allocates colors when
+ run on a display with a limited amount of colors, e.g. 8 bit / 256 color
+ displays.
+
+ The color specification must be set before you create the QApplication
+ object.
+
+ The options are:
\list
- \o For 256-color displays which have at best a 256 color true
- color visual, the default visual is used, and colors are
- allocated from a color cube. The color cube is the 6x6x6 (216
- color) "Web palette" (the red, green, and blue components
- always have one of the following values: 0x00, 0x33, 0x66,
- 0x99, 0xCC, or 0xFF), but the number of colors can be changed
- by the \e -ncols option. The user can force the application to
- use the true color visual with the \link
- QApplication::QApplication() -visual \endlink option.
- \o For 256-color displays which have a true color visual with more
- than 256 colors, use that visual. Silicon Graphics X servers
- have this feature, for example. They provide an 8 bit visual
- by default but can deliver true color when asked.
+ \o QApplication::NormalColor. This is the default color allocation
+ strategy. Use this option if your application uses buttons, menus,
+ texts and pixmaps with few colors. With this option, the
+ application uses system global colors. This works fine for most
+ applications under X11, but on Windows machines it may cause
+ dithering of non-standard colors.
+ \o QApplication::CustomColor. Use this option if your application
+ needs a small number of custom colors. On X11, this option is the
+ same as NormalColor. On Windows, Qt creates a Windows palette, and
+ allocates colors to it on demand.
+ \o QApplication::ManyColor. Use this option if your application is
+ very color hungry, e.g., it requires thousands of colors. \br
+ Under X11 the effect is:
+ \list
+ \o For 256-color displays which have at best a 256 color true
+ color visual, the default visual is used, and colors are
+ allocated from a color cube. The color cube is the 6x6x6
+ (216 color) "Web palette" (the red, green, and blue
+ components always have one of the following values: 0x00,
+ 0x33, 0x66, 0x99, 0xCC, or 0xFF), but the number of colors
+ can be changed by the \e -ncols option. The user can force
+ the application to use the true color visual with the
+ \l{QApplication::QApplication()}{-visual} option.
+ \o For 256-color displays which have a true color visual with
+ more than 256 colors, use that visual. Silicon Graphics X
+ servers this feature, for example. They provide an 8 bit
+ visual by default but can deliver true color when asked.
+ \endlist
+ On Windows, Qt creates a Windows palette, and fills it with a color
+ cube.
\endlist
- On Windows, Qt creates a Windows palette, and fills it with a color cube.
- \endlist
- Be aware that the CustomColor and ManyColor choices may lead to colormap
- flashing: The foreground application gets (most) of the available
- colors, while the background windows will look less attractive.
+ Be aware that the CustomColor and ManyColor choices may lead to colormap
+ flashing: The foreground application gets (most) of the available colors,
+ while the background windows will look less attractive.
- Example:
+ Example:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 2
@@ -1624,10 +1608,9 @@ void QApplication::setColorSpec(int spec)
\brief the minimum size that any GUI element that the user can interact
with should have
- For example, no button should be resized to be smaller than the
- global strut size. The strut size should be considered when
- reimplementing GUI controls that may be used on touch-screens or
- similar I/O devices.
+ For example, no button should be resized to be smaller than the global
+ strut size. The strut size should be considered when reimplementing GUI
+ controls that may be used on touch-screens or similar I/O devices.
Example:
@@ -1661,12 +1644,11 @@ QPalette QApplication::palette()
\fn QPalette QApplication::palette(const QWidget* widget)
\overload
- If a \a widget is passed, the default palette for the
- widget's class is returned. This may or may not be the application
- palette. In most cases there isn't a special palette for certain
- types of widgets, but one notable exception is the popup menu
- under Windows, if the user has defined a special background color
- for menus in the display settings.
+ If a \a widget is passed, the default palette for the widget's class is
+ returned. This may or may not be the application palette. In most cases
+ there is no special palette for certain types of widgets, but one notable
+ exception is the popup menu under Windows, if the user has defined a
+ special background color for menus in the display settings.
\sa setPalette(), QWidget::palette()
*/
@@ -1760,26 +1742,26 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char*
}
/*!
- Changes the default application palette to \a palette.
+ Changes the default application palette to \a palette.
- If \a className is passed, the change applies only to widgets that
- inherit \a className (as reported by QObject::inherits()). If
- \a className is left 0, the change affects all widgets, thus overriding
- any previously set class specific palettes.
+ If \a className is passed, the change applies only to widgets that inherit
+ \a className (as reported by QObject::inherits()). If \a className is left
+ 0, the change affects all widgets, thus overriding any previously set class
+ specific palettes.
- The palette may be changed according to the current GUI style in
- QStyle::polish().
+ The palette may be changed according to the current GUI style in
+ QStyle::polish().
- \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
- When using style sheets, the palette of a widget can be customized using the "color",
- "background-color", "selection-color", "selection-background-color" and
- "alternate-background-color".
+ \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
+ When using style sheets, the palette of a widget can be customized using
+ the "color", "background-color", "selection-color",
+ "selection-background-color" and "alternate-background-color".
- Note that some styles do not use the palette for all drawing,
- for instance, if they make use of native theme engines. This is
- the case for the Windows XP, Windows Vista, and Mac OS X styles.
+ \note Some styles do not use the palette for all drawing, for instance, if
+ they make use of native theme engines. This is the case for the Windows XP,
+ Windows Vista, and Mac OS X styles.
- \sa QWidget::setPalette(), palette(), QStyle::polish()
+ \sa QWidget::setPalette(), palette(), QStyle::polish()
*/
void QApplication::setPalette(const QPalette &palette, const char* className)
@@ -1884,15 +1866,15 @@ QFont QApplication::font(const char *className)
/*!
- Changes the default application font to \a font. If \a className
- is passed, the change applies only to classes that inherit \a
- className (as reported by QObject::inherits()).
+ Changes the default application font to \a font. If \a className is passed,
+ the change applies only to classes that inherit \a className (as reported
+ by QObject::inherits()).
- On application start-up, the default font depends on the window
- system. It can vary depending on both the window system version and
- the locale. This function lets you override the default font; but
- overriding may be a bad idea because, for example, some locales need
- extra large fonts to support their special characters.
+ On application start-up, the default font depends on the window system. It
+ can vary depending on both the window system version and the locale. This
+ function lets you override the default font; but overriding may be a bad
+ idea because, for example, some locales need extra large fonts to support
+ their special characters.
\warning Do not use this function in conjunction with \l{Qt Style Sheets}.
The font of an application can be customized using the "font" style sheet
@@ -1994,11 +1976,10 @@ void QApplication::setWindowIcon(const QIcon &icon)
}
/*!
- Returns a list of the top-level widgets (windows) in the
- application.
+ Returns a list of the top-level widgets (windows) in the application.
- Note that some of the top-level widgets may be hidden, for
- example a tooltip if no tooltip is currently shown.
+ \note Some of the top-level widgets may be hidden, for example a tooltip if
+ no tooltip is currently shown.
Example:
@@ -2024,7 +2005,7 @@ QWidgetList QApplication::topLevelWidgets()
The list is empty (QList::isEmpty()) if there are no widgets.
- Note that some of the widgets may be hidden.
+ \note Some of the widgets may be hidden.
Example:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 5
@@ -2043,10 +2024,10 @@ QWidgetList QApplication::allWidgets()
}
/*!
- Returns the application widget that has the keyboard input focus, or
- 0 if no widget in this application has the focus.
+ Returns the application widget that has the keyboard input focus, or 0 if
+ no widget in this application has the focus.
- \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
+ \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
*/
QWidget *QApplication::focusWidget()
@@ -2080,9 +2061,13 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
QWidget *prev = focus_widget;
focus_widget = focus;
- if (prev && reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason &&
- prev->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *qic = prev->inputContext();
+ if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
+ && prev->testAttribute(Qt::WA_InputMethodEnabled))
+ // Do reset the input context, in case the new focus widget won't accept keyboard input
+ // or it is not created fully yet.
+ || (focus_widget && (!focus_widget->testAttribute(Qt::WA_InputMethodEnabled)
+ || !focus_widget->testAttribute(Qt::WA_WState_Created))))) {
+ QInputContext *qic = prev->inputContext();
if(qic) {
qic->reset();
qic->setFocusWidget(0);
@@ -2127,12 +2112,12 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
/*!
- Returns the application top-level window that has the keyboard input
- focus, or 0 if no application window has the focus. Note that
- there might be an activeWindow() even if there is no focusWidget(),
- for example if no widget in that window accepts key events.
+ Returns the application top-level window that has the keyboard input focus,
+ or 0 if no application window has the focus. There might be an
+ activeWindow() even if there is no focusWidget(), for example if no widget
+ in that window accepts key events.
- \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
+ \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
*/
QWidget *QApplication::activeWindow()
@@ -2141,9 +2126,9 @@ QWidget *QApplication::activeWindow()
}
/*!
- Returns display (screen) font metrics for the application font.
+ Returns display (screen) font metrics for the application font.
- \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
+ \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
*/
QFontMetrics QApplication::fontMetrics()
@@ -2155,19 +2140,20 @@ QFontMetrics QApplication::fontMetrics()
/*!
Closes all top-level windows.
- This function is particularly useful for applications with many
- top-level windows. It could, for example, be connected to a
- \gui{Exit} entry in the \gui{File} menu:
+ This function is particularly useful for applications with many top-level
+ windows. It could, for example, be connected to a \gui{Exit} entry in the
+ \gui{File} menu:
\snippet examples/mainwindows/mdi/mainwindow.cpp 0
- The windows are closed in random order, until one window does not
- accept the close event. The application quits when the last window
- was successfully closed; this can be turned off by setting \l
- quitOnLastWindowClosed to false.
+ The windows are closed in random order, until one window does not accept
+ the close event. The application quits when the last window was
+ successfully closed; this can be turned off by setting
+ \l quitOnLastWindowClosed to false.
- \sa quitOnLastWindowClosed, lastWindowClosed() QWidget::close(), QWidget::closeEvent(), lastWindowClosed(),
- quit(), topLevelWidgets(), QWidget::isWindow()
+ \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
+ QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
+ QWidget::isWindow()
*/
void QApplication::closeAllWindows()
{
@@ -2190,11 +2176,11 @@ void QApplication::closeAllWindows()
}
/*!
- Displays a simple message box about Qt. The message includes the
- version number of Qt being used by the application.
+ Displays a simple message box about Qt. The message includes the version
+ number of Qt being used by the application.
- This is useful for inclusion in the \gui Help menu of an application,
- as shown in the \l{mainwindows/menus}{Menus} example.
+ This is useful for inclusion in the \gui Help menu of an application, as
+ shown in the \l{mainwindows/menus}{Menus} example.
This function is a convenience slot for QMessageBox::aboutQt().
*/
@@ -2215,22 +2201,20 @@ void QApplication::aboutQt()
/*!
\fn void QApplication::lastWindowClosed()
- This signal is emitted from QApplication::exec() when the last
- visible primary window (i.e. window with no parent) with the
- Qt::WA_QuitOnClose attribute set is closed.
+ This signal is emitted from QApplication::exec() when the last visible
+ primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
+ attribute set is closed.
By default,
\list
+ \o this attribute is set for all widgets except transient windows such
+ as splash screens, tool windows, and popup menus
- \i this attribute is set for all widgets except transient windows
- such as splash screens, tool windows, and popup menus
-
- \i QApplication implicitly quits when this signal is emitted.
-
+ \o QApplication implicitly quits when this signal is emitted.
\endlist
- This feature be turned off by setting \l quitOnLastWindowClosed to
+ This feature can be turned off by setting \l quitOnLastWindowClosed to
false.
\sa QWidget::close()
@@ -2240,15 +2224,15 @@ void QApplication::aboutQt()
\since 4.1
\fn void QApplication::focusChanged(QWidget *old, QWidget *now)
- This signal is emitted when the widget that has keyboard focus
- changed from \a old to \a now, i.e. because the user pressed the
- tab-key, clicked into a widget or changed the active window. Note
- that both \a old and \a now can be the null-pointer.
+ This signal is emitted when the widget that has keyboard focus changed from
+ \a old to \a now, i.e., because the user pressed the tab-key, clicked into
+ a widget or changed the active window. Both \a old and \a now can be the
+ null-pointer.
- The signal is emitted after both widget have been notified about
- the change through QFocusEvent.
+ The signal is emitted after both widget have been notified about the change
+ through QFocusEvent.
- \sa QWidget::setFocus() QWidget::clearFocus() Qt::FocusReason
+ \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
*/
/*!
@@ -2257,10 +2241,10 @@ void QApplication::aboutQt()
This signal is emitted when application fonts are loaded or removed.
- \sa QFontDatabase::addApplicationFont()
- \sa QFontDatabase::addApplicationFontFromData()
- \sa QFontDatabase::removeAllApplicationFonts()
- \sa QFontDatabase::removeApplicationFont()
+ \sa QFontDatabase::addApplicationFont(),
+ QFontDatabase::addApplicationFontFromData(),
+ QFontDatabase::removeAllApplicationFonts(),
+ QFontDatabase::removeApplicationFont()
*/
#ifndef QT_NO_TRANSLATION
@@ -2357,18 +2341,17 @@ void QApplication::syncX() {} // do nothing
\fn void QApplication::setActiveWindow(QWidget* active)
Sets the active window to the \a active widget in response to a system
- event. The function is called from the platform specific event
- handlers.
+ event. The function is called from the platform specific event handlers.
- \warning This function does \e not set the keyboard focus to the
- active widget. Call QWidget::activateWindow() instead.
+ \warning This function does \e not set the keyboard focus to the active
+ widget. Call QWidget::activateWindow() instead.
- It sets the activeWindow() and focusWidget() attributes and sends
- proper \l{QEvent::WindowActivate}{WindowActivate}/\l{QEvent::WindowDeactivate}{WindowDeactivate}
- and \l{QEvent::FocusIn}{FocusIn}/\l{QEvent::FocusOut}{FocusOut} events
- to all appropriate widgets. The window will then be painted in
- active state (e.g. cursors in line edits will blink), and it will
- have tool tips enabled.
+ It sets the activeWindow() and focusWidget() attributes and sends proper
+ \l{QEvent::WindowActivate}{WindowActivate}/\l{QEvent::WindowDeactivate}
+ {WindowDeactivate} and \l{QEvent::FocusIn}{FocusIn}/\l{QEvent::FocusOut}
+ {FocusOut} events to all appropriate widgets. The window will then be
+ painted in active state (e.g. cursors in line edits will blink), and it
+ will have tool tips enabled.
\sa activeWindow(), QWidget::activateWindow()
*/
@@ -2467,7 +2450,9 @@ void QApplication::setActiveWindow(QWidget* act)
} else {
// If the focus widget is not in the activate_window, clear the focus
w = QApplicationPrivate::focus_widget;
- if (w && !QApplicationPrivate::active_window->isAncestorOf(w))
+ if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus)
+ QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason);
+ else if (!QApplicationPrivate::active_window->isAncestorOf(w))
QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
}
}
@@ -2512,11 +2497,11 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
}
/*!
- \fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave)
- \internal
+ \fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave)
+ \internal
- Creates the proper Enter/Leave event when widget \a enter is entered
- and widget \a leave is left.
+ Creates the proper Enter/Leave event when widget \a enter is entered and
+ widget \a leave is left.
*/
#if defined(Q_WS_WIN)
extern void qt_win_set_cursor(QWidget *, bool);
@@ -3033,11 +3018,11 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
/*!
Returns the desktop widget (also called the root window).
- Note that the desktop may be composed of multiple screens, so it would be
- incorrect, for example, to attempt to \e center some widget in the
- desktop's geometry. QDesktopWidget has various functions for obtaining
- useful geometries upon the desktop, such as QDesktopWidget::screenGeometry()
- and QDesktopWidget::availableGeometry().
+ The desktop may be composed of multiple screens, so it would be incorrect,
+ for example, to attempt to \e center some widget in the desktop's geometry.
+ QDesktopWidget has various functions for obtaining useful geometries upon
+ the desktop, such as QDesktopWidget::screenGeometry() and
+ QDesktopWidget::availableGeometry().
On X11, it is also possible to draw on the desktop.
*/
@@ -3052,10 +3037,10 @@ QDesktopWidget *QApplication::desktop()
#ifndef QT_NO_CLIPBOARD
/*!
- Returns a pointer to the application global clipboard.
+ Returns a pointer to the application global clipboard.
- \note The QApplication object should already be constructed before
- accessing the clipboard.
+ \note The QApplication object should already be constructed before
+ accessing the clipboard.
*/
QClipboard *QApplication::clipboard()
{
@@ -3071,11 +3056,11 @@ QClipboard *QApplication::clipboard()
#endif // QT_NO_CLIPBOARD
/*!
- Sets whether Qt should use the system's standard colors, fonts,
- etc., to \a on. By default, this is true.
+ Sets whether Qt should use the system's standard colors, fonts, etc., to
+ \a on. By default, this is true.
- This function must be called before creating the QApplication
- object, like this:
+ This function must be called before creating the QApplication object, like
+ this:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
@@ -3087,8 +3072,8 @@ void QApplication::setDesktopSettingsAware(bool on)
}
/*!
- Returns true if Qt is set to use the system's standard colors,
- fonts, etc.; otherwise returns false. The default is true.
+ Returns true if Qt is set to use the system's standard colors, fonts, etc.;
+ otherwise returns false. The default is true.
\sa setDesktopSettingsAware()
*/
@@ -3098,17 +3083,17 @@ bool QApplication::desktopSettingsAware()
}
/*!
- Returns the current state of the modifier keys on the keyboard. The
- current state is updated sychronously as the event queue is emptied
- of events that will spontaneously change the keyboard state
- (QEvent::KeyPress and QEvent::KeyRelease events).
+ Returns the current state of the modifier keys on the keyboard. The current
+ state is updated sychronously as the event queue is emptied of events that
+ will spontaneously change the keyboard state (QEvent::KeyPress and
+ QEvent::KeyRelease events).
- It should be noted this may not reflect the actual keys held on the
- input device at the time of calling but rather the modifiers as
- last reported in one of the above events. If no keys are being held
- Qt::NoModifier is returned.
+ It should be noted this may not reflect the actual keys held on the input
+ device at the time of calling but rather the modifiers as last reported in
+ one of the above events. If no keys are being held Qt::NoModifier is
+ returned.
- \sa mouseButtons()
+ \sa mouseButtons()
*/
Qt::KeyboardModifiers QApplication::keyboardModifiers()
@@ -3117,17 +3102,17 @@ Qt::KeyboardModifiers QApplication::keyboardModifiers()
}
/*!
- Returns the current state of the buttons on the mouse. The current
- state is updated syncronously as the event queue is emptied of
- events that will spontaneously change the mouse state
- (QEvent::MousePress and QEvent::MouseRelease events).
+ Returns the current state of the buttons on the mouse. The current state is
+ updated syncronously as the event queue is emptied of events that will
+ spontaneously change the mouse state (QEvent::MouseButtonPress and
+ QEvent::MouseButtonRelease events).
- It should be noted this may not reflect the actual buttons held on
- theinput device at the time of calling but rather the mouse buttons
- as last reported in one of the above events. If no mouse buttons are
- being held Qt::NoButton is returned.
+ It should be noted this may not reflect the actual buttons held on the
+ input device at the time of calling but rather the mouse buttons as last
+ reported in one of the above events. If no mouse buttons are being held
+ Qt::NoButton is returned.
- \sa keyboardModifiers()
+ \sa keyboardModifiers()
*/
Qt::MouseButtons QApplication::mouseButtons()
@@ -3136,43 +3121,40 @@ Qt::MouseButtons QApplication::mouseButtons()
}
/*!
- \fn bool QApplication::isSessionRestored() const
+ \fn bool QApplication::isSessionRestored() const
- Returns true if the application has been restored from an earlier
- \link session.html session\endlink; otherwise returns false.
+ Returns true if the application has been restored from an earlier
+ \l{Session Management}{session}; otherwise returns false.
- \sa sessionId(), commitData(), saveState()
+ \sa sessionId(), commitData(), saveState()
*/
/*!
- \fn QString QApplication::sessionId() const
+ \fn QString QApplication::sessionId() const
- Returns the current \link session.html session's\endlink identifier.
+ Returns the current \l{Session Management}{session's} identifier.
- If the application has been restored from an earlier session, this
- identifier is the same as it was in that previous session.
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in that previous session. The session
+ identifier is guaranteed to be unique both for different applications
+ and for different instances of the same application.
- The session identifier is guaranteed to be unique both for different
- applications and for different instances of the same application.
-
- \sa isSessionRestored(), sessionKey(), commitData(), saveState()
- */
+ \sa isSessionRestored(), sessionKey(), commitData(), saveState()
+*/
/*!
- \fn QString QApplication::sessionKey() const
+ \fn QString QApplication::sessionKey() const
- Returns the session key in the current \link session.html
- session\endlink.
+ Returns the session key in the current \l{Session Management}{session}.
- If the application has been restored from an earlier session, this
- key is the same as it was when the previous session ended.
+ If the application has been restored from an earlier session, this key is
+ the same as it was when the previous session ended.
- The session key changes with every call of commitData() or
- saveState().
+ The session key changes with every call of commitData() or saveState().
- \sa isSessionRestored(), sessionId(), commitData(), saveState()
- */
+ \sa isSessionRestored(), sessionId(), commitData(), saveState()
+*/
#ifndef QT_NO_SESSIONMANAGER
bool QApplication::isSessionRestored() const
{
@@ -3195,59 +3177,57 @@ QString QApplication::sessionKey() const
-
-
/*!
- \since 4.2
- \fn void QApplication::commitDataRequest(QSessionManager &manager)
+ \since 4.2
+ \fn void QApplication::commitDataRequest(QSessionManager &manager)
- This signal deals with \link session.html session
- management\endlink. It is emitted when the QSessionManager wants the
- application to commit all its data.
+ This signal deals with \l{Session Management}{session management}. It is
+ emitted when the QSessionManager wants the application to commit all its
+ data.
- Usually this means saving all open files, after getting
- permission from the user. Furthermore you may want to provide a means
- by which the user can cancel the shutdown.
+ Usually this means saving all open files, after getting permission from
+ the user. Furthermore you may want to provide a means by which the user
+ can cancel the shutdown.
- Note that you should not exit the application when called.
- Instead, the session manager may or may not do this afterwards,
- depending on the context.
+ You should not exit the application within this signal. Instead,
+ the session manager may or may not do this afterwards, depending on the
+ context.
- \warning Within this signal, no user interaction is possible, \e
- unless you ask the \a manager for explicit permission. See
- QSessionManager::allowsInteraction() and
- QSessionManager::allowsErrorInteraction() for details and example
- usage.
+ \warning Within this signal, no user interaction is possible, \e
+ unless you ask the \a manager for explicit permission. See
+ QSessionManager::allowsInteraction() and
+ QSessionManager::allowsErrorInteraction() for details and example
+ usage.
- Note: You should use Qt::DirectConnection when connecting to this signal.
+ \note You should use Qt::DirectConnection when connecting to this signal.
- \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
+ \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
*/
/*!
- This function deals with \link session.html session
- management\endlink. It is invoked when the QSessionManager wants the
- application to commit all its data.
+ This function deals with \l{Session Management}{session management}. It is
+ invoked when the QSessionManager wants the application to commit all its
+ data.
- Usually this means saving all open files, after getting
- permission from the user. Furthermore you may want to provide a means
- by which the user can cancel the shutdown.
+ Usually this means saving all open files, after getting permission from the
+ user. Furthermore you may want to provide a means by which the user can
+ cancel the shutdown.
- Note that you should not exit the application within this function.
- Instead, the session manager may or may not do this afterwards,
- depending on the context.
+ You should not exit the application within this function. Instead, the
+ session manager may or may not do this afterwards, depending on the
+ context.
- \warning Within this function, no user interaction is possible, \e
- unless you ask the \a manager for explicit permission. See
- QSessionManager::allowsInteraction() and
- QSessionManager::allowsErrorInteraction() for details and example
- usage.
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the \a manager for explicit permission. See
+ QSessionManager::allowsInteraction() and
+ QSessionManager::allowsErrorInteraction() for details and example
+ usage.
- The default implementation requests interaction and sends a close
- event to all visible top-level widgets. If any event was
- rejected, the shutdown is canceled.
+ The default implementation requests interaction and sends a close event to
+ all visible top-level widgets. If any event was rejected, the shutdown is
+ canceled.
- \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
+ \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
*/
#ifndef QT_NO_SESSIONMANAGER
void QApplication::commitData(QSessionManager& manager )
@@ -3273,58 +3253,54 @@ void QApplication::commitData(QSessionManager& manager )
}
/*!
- \since 4.2
- \fn void QApplication::saveStateRequest(QSessionManager &manager)
+ \since 4.2
+ \fn void QApplication::saveStateRequest(QSessionManager &manager)
- This signal deals with \link session.html session
- management\endlink. It is invoked when the
- \link QSessionManager session manager \endlink wants the application
- to preserve its state for a future session.
+ This signal deals with \l{Session Management}{session management}. It is
+ invoked when the \l{QSessionManager}{session manager} wants the application
+ to preserve its state for a future session.
- For example, a text editor would create a temporary file that
- includes the current contents of its edit buffers, the location of
- the cursor and other aspects of the current editing session.
+ For example, a text editor would create a temporary file that includes the
+ current contents of its edit buffers, the location of the cursor and other
+ aspects of the current editing session.
- Note that you should never exit the application within this
- signal. Instead, the session manager may or may not do this
- afterwards, depending on the context. Futhermore, most session
- managers will very likely request a saved state immediately after
- the application has been started. This permits the session manager
- to learn about the application's restart policy.
+ You should never exit the application within this signal. Instead, the
+ session manager may or may not do this afterwards, depending on the
+ context. Futhermore, most session managers will very likely request a saved
+ state immediately after the application has been started. This permits the
+ session manager to learn about the application's restart policy.
- \warning Within this function, no user interaction is possible, \e
- unless you ask the \a manager for explicit permission. See
- QSessionManager::allowsInteraction() and
- QSessionManager::allowsErrorInteraction() for details.
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the \a manager for explicit permission. See
+ QSessionManager::allowsInteraction() and
+ QSessionManager::allowsErrorInteraction() for details.
- Note:: You should use Qt::DirectConnection when connecting to this signal.
+ \note You should use Qt::DirectConnection when connecting to this signal.
- \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
+ \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
*/
/*!
- This function deals with \link session.html session
- management\endlink. It is invoked when the
- \link QSessionManager session manager \endlink wants the application
- to preserve its state for a future session.
+ This function deals with \l{Session Management}{session management}. It is
+ invoked when the \l{QSessionManager}{session manager} wants the application
+ to preserve its state for a future session.
- For example, a text editor would create a temporary file that
- includes the current contents of its edit buffers, the location of
- the cursor and other aspects of the current editing session.
+ For example, a text editor would create a temporary file that includes the
+ current contents of its edit buffers, the location of the cursor and other
+ aspects of the current editing session.
- Note that you should never exit the application within this
- function. Instead, the session manager may or may not do this
- afterwards, depending on the context. Futhermore, most session
- managers will very likely request a saved state immediately after
- the application has been started. This permits the session manager
- to learn about the application's restart policy.
+ You should never exit the application within this function. Instead, the
+ session manager may or may not do this afterwards, depending on the
+ context. Futhermore, most session managers will very likely request a saved
+ state immediately after the application has been started. This permits the
+ session manager to learn about the application's restart policy.
- \warning Within this function, no user interaction is possible, \e
- unless you ask the \a manager for explicit permission. See
- QSessionManager::allowsInteraction() and
- QSessionManager::allowsErrorInteraction() for details.
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the \a manager for explicit permission. See
+ QSessionManager::allowsInteraction() and
+ QSessionManager::allowsErrorInteraction() for details.
- \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
+ \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
*/
void QApplication::saveState(QSessionManager &manager)
@@ -3348,13 +3324,12 @@ void QApplication::setStartDragTime(int ms)
\brief the time in milliseconds that a mouse button must be held down
before a drag and drop operation will begin
- If you support drag and drop in your application, and want to start a
- drag and drop operation after the user has held down a mouse button for
- a certain amount of time, you should use this property's value as the
- delay.
+ If you support drag and drop in your application, and want to start a drag
+ and drop operation after the user has held down a mouse button for a
+ certain amount of time, you should use this property's value as the delay.
- Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit,
- for starting a drag.
+ Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
+ starting a drag.
The default value is 500 ms.
@@ -3367,9 +3342,9 @@ int QApplication::startDragTime()
}
/*
- Sets the distance after which a drag should start to \a l pixels.
+ Sets the distance after which a drag should start to \a l pixels.
- \sa startDragDistance()
+ \sa startDragDistance()
*/
void QApplication::setStartDragDistance(int l)
@@ -3380,15 +3355,14 @@ void QApplication::setStartDragDistance(int l)
/*!
\property QApplication::startDragDistance
- If you support drag and drop in your application, and want to start a
- drag and drop operation after the user has moved the cursor a certain
- distance with a button held down, you should use this property's value
- as the minimum distance required.
+ If you support drag and drop in your application, and want to start a drag
+ and drop operation after the user has moved the cursor a certain distance
+ with a button held down, you should use this property's value as the
+ minimum distance required.
- For example, if the mouse position of the click is stored in \c
- startPos and the current position (e.g. in the mouse move event) is
- \c currentPos, you can find out if a drag should be started with code
- like this:
+ For example, if the mouse position of the click is stored in \c startPos
+ and the current position (e.g. in the mouse move event) is \c currentPos,
+ you can find out if a drag should be started with code like this:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 7
@@ -3434,14 +3408,14 @@ int QApplication::startDragDistance()
\sa layoutDirection(), isRightToLeft()
*/
-/*! \property QApplication::layoutDirection
-
- \brief the default layout direction for this application
+/*!
+ \property QApplication::layoutDirection
+ \brief the default layout direction for this application
- On system start-up, the default layout direction depends on the
- application's language.
+ On system start-up, the default layout direction depends on the
+ application's language.
- \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
+ \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
*/
void QApplication::setLayoutDirection(Qt::LayoutDirection direction)
@@ -3465,11 +3439,12 @@ Qt::LayoutDirection QApplication::layoutDirection()
}
-/*! \obsolete
+/*!
+ \obsolete
- Strips out vertical alignment flags and transforms an
- alignment \a align of Qt::AlignLeft into Qt::AlignLeft or
- Qt::AlignRight according to the language used.
+ Strips out vertical alignment flags and transforms an alignment \a align
+ of Qt::AlignLeft into Qt::AlignLeft or Qt::AlignRight according to the
+ language used.
*/
#ifdef QT3_SUPPORT
@@ -3485,8 +3460,8 @@ Qt::Alignment QApplication::horizontalAlignment(Qt::Alignment align)
Returns the active application override cursor.
- This function returns 0 if no application cursor has been defined
- (i.e. the internal cursor stack is empty).
+ This function returns 0 if no application cursor has been defined (i.e. the
+ internal cursor stack is empty).
\sa setOverrideCursor(), restoreOverrideCursor()
*/
@@ -3499,9 +3474,10 @@ QCursor *QApplication::overrideCursor()
/*!
Changes the currently active application override cursor to \a cursor.
- This function has no effect if setOverrideCursor() wasn't called.
+ This function has no effect if setOverrideCursor() was not called.
- \sa setOverrideCursor() overrideCursor() restoreOverrideCursor() QWidget::setCursor()
+ \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
+ QWidget::setCursor()
*/
void QApplication::changeOverrideCursor(const QCursor &cursor)
{
@@ -3515,8 +3491,8 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
/*!
\fn void QApplication::setOverrideCursor(const QCursor &cursor, bool replace)
- Use changeOverrideCursor(\a cursor) (if \a replace is true)
- or setOverrideCursor(\a cursor) (if \a replace is false).
+ Use changeOverrideCursor(\a cursor) (if \a replace is true) or
+ setOverrideCursor(\a cursor) (if \a replace is false).
*/
/*!
@@ -3524,29 +3500,26 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
the value that was set to exit() (which is 0 if exit() is called via
quit()).
- It is necessary to call this function to start event handling. The
- main event loop receives events from the window system and
- dispatches these to the application widgets.
+ It is necessary to call this function to start event handling. The main
+ event loop receives events from the window system and dispatches these to
+ the application widgets.
+
+ Generally, no user interaction can take place before calling exec(). As a
+ special case, modal widgets like QMessageBox can be used before calling
+ exec(), because modal widgets call exec() to start a local event loop.
- Generally speaking, no user interaction can take place before
- calling exec(). As a special case, modal widgets like QMessageBox
- can be used before calling exec(), because modal widgets call
- exec() to start a local event loop.
-
- To make your application perform idle processing, i.e. executing a
- special function whenever there are no pending events, use a
- QTimer with 0 timeout. More advanced idle processing schemes can
- be achieved using processEvents().
+ To make your application perform idle processing, i.e., executing a special
+ function whenever there are no pending events, use a QTimer with 0 timeout.
+ More advanced idle processing schemes can be achieved using processEvents().
We recommend that you connect clean-up code to the
- \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
- your application's \c{main()} function because on some platforms the
- QApplication::exec() call may not return. For example, on Windows
- when the user logs off, the system terminates the process after Qt
- closes all top-level windows. Hence, there is no guarantee that the
- application will have time to exit its event loop and execute code at
- the end of the \c{main()} function after the QApplication::exec()
- call.
+ \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
+ application's \c{main()} function because on some platforms the
+ QApplication::exec() call may not return. For example, on Windows when the
+ user logs off, the system terminates the process after Qt closes all
+ top-level windows. Hence, there is no guarantee that the application will
+ have time to exit its event loop and execute code at the end of the
+ \c{main()} function after the QApplication::exec() call.
\sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
QCoreApplication::exec()
@@ -4094,101 +4067,98 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
/*!
- \class QSessionManager
- \brief The QSessionManager class provides access to the session manager.
-
- \ingroup application
- \ingroup environment
-
- A session manager in a desktop environment (in which Qt GUI
- applications live) keeps track of a session, which is a group of
- running applications, each of which has a particular state. The
- state of an application contains (most notably) the documents the
- application has open and the position and size of its windows.
-
- The session manager is used to save the session, e.g. when the
- machine is shut down, and to restore a session, e.g. when the
- machine is started up. We recommend that you use QSettings to save
- an individual application's settings, e.g. window positions,
- recently used files, etc. When the application is restarted by the
- session manager, you can restore the settings.
-
- QSessionManager provides an interface between the application
- and the session manager so that the program can work well with the
- session manager. In Qt, session management requests for action are
- handled by the two virtual functions QApplication::commitData()
- and QApplication::saveState(). Both provide a reference to a
- session manager object as argument, to allow the application to
- communicate with the session manager. The session manager can only
- be accessed through these functions.
-
- No user interaction is possible \e unless the application gets
- explicit permission from the session manager. You ask for permission
- by calling allowsInteraction() or, if it's really urgent,
- allowsErrorInteraction(). Qt does not enforce this, but the session
- manager may.
-
- You can try to abort the shutdown process by calling cancel(). The
- default commitData() function does this if some top-level window
- rejected its closeEvent().
-
- For sophisticated session managers provided on Unix/X11, QSessionManager
- offers further possibilities to fine-tune an application's session
- management behavior: setRestartCommand(), setDiscardCommand(),
- setRestartHint(), setProperty(), requestPhase2(). See the respective
- function descriptions for further details.
-
- \sa QApplication, {Session Management}
+ \class QSessionManager
+ \brief The QSessionManager class provides access to the session manager.
+
+ \ingroup application
+ \ingroup environment
+
+ A session manager in a desktop environment (in which Qt GUI applications
+ live) keeps track of a session, which is a group of running applications,
+ each of which has a particular state. The state of an application contains
+ (most notably) the documents the application has open and the position and
+ size of its windows.
+
+ The session manager is used to save the session, e.g., when the machine is
+ shut down, and to restore a session, e.g., when the machine is started up.
+ We recommend that you use QSettings to save an application's settings,
+ for example, window positions, recently used files, etc. When the
+ application is restarted by the session manager, you can restore the
+ settings.
+
+ QSessionManager provides an interface between the application and the
+ session manager so that the program can work well with the session manager.
+ In Qt, session management requests for action are handled by the two
+ virtual functions QApplication::commitData() and QApplication::saveState().
+ Both provide a reference to a session manager object as argument, to allow
+ the application to communicate with the session manager. The session
+ manager can only be accessed through these functions.
+
+ No user interaction is possible \e unless the application gets explicit
+ permission from the session manager. You ask for permission by calling
+ allowsInteraction() or, if it is really urgent, allowsErrorInteraction().
+ Qt does not enforce this, but the session manager may.
+
+ You can try to abort the shutdown process by calling cancel(). The default
+ commitData() function does this if some top-level window rejected its
+ closeEvent().
+
+ For sophisticated session managers provided on Unix/X11, QSessionManager
+ offers further possibilities to fine-tune an application's session
+ management behavior: setRestartCommand(), setDiscardCommand(),
+ setRestartHint(), setProperty(), requestPhase2(). See the respective
+ function descriptions for further details.
+
+ \sa QApplication, {Session Management}
*/
/*! \enum QSessionManager::RestartHint
- This enum type defines the circumstances under which this
- application wants to be restarted by the session manager. The
- current values are
+ This enum type defines the circumstances under which this application wants
+ to be restarted by the session manager. The current values are:
- \value RestartIfRunning if the application is still running when
- the session is shut down, it wants to be restarted at the start of
- the next session.
+ \value RestartIfRunning If the application is still running when the
+ session is shut down, it wants to be restarted
+ at the start of the next session.
- \value RestartAnyway the application wants to be started at the
- start of the next session, no matter what. (This is useful for
- utilities that run just after startup and then quit.)
+ \value RestartAnyway The application wants to be started at the
+ start of the next session, no matter what.
+ (This is useful for utilities that run just
+ after startup and then quit.)
- \value RestartImmediately the application wants to be started
- immediately whenever it is not running.
+ \value RestartImmediately The application wants to be started immediately
+ whenever it is not running.
- \value RestartNever the application does not want to be restarted
- automatically.
+ \value RestartNever The application does not want to be restarted
+ automatically.
- The default hint is \c RestartIfRunning.
+ The default hint is \c RestartIfRunning.
*/
/*!
- \fn QString QSessionManager::sessionId() const
+ \fn QString QSessionManager::sessionId() const
- Returns the identifier of the current session.
+ Returns the identifier of the current session.
- If the application has been restored from an earlier session, this
- identifier is the same as it was in that earlier session.
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in the earlier session.
- \sa sessionKey(), QApplication::sessionId()
- */
+ \sa sessionKey(), QApplication::sessionId()
+*/
/*!
- \fn QString QSessionManager::sessionKey() const
+ \fn QString QSessionManager::sessionKey() const
- Returns the session key in the current session.
+ Returns the session key in the current session.
- If the application has been restored from an earlier session, this
- key is the same as it was when the previous session ended.
+ If the application has been restored from an earlier session, this key is
+ the same as it was when the previous session ended.
- The session key changes with every call of commitData() or
- saveState().
+ The session key changes with every call of commitData() or saveState().
- \sa sessionId(), QApplication::sessionKey()
- */
+ \sa sessionId(), QApplication::sessionKey()
+*/
/*!
\fn void* QSessionManager::handle() const
@@ -4197,120 +4167,116 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
*/
/*!
- \fn bool QSessionManager::allowsInteraction()
+ \fn bool QSessionManager::allowsInteraction()
- Asks the session manager for permission to interact with the
- user. Returns true if interaction is permitted; otherwise
- returns false.
+ Asks the session manager for permission to interact with the user. Returns
+ true if interaction is permitted; otherwise returns false.
- The rationale behind this mechanism is to make it possible to
- synchronize user interaction during a shutdown. Advanced session
- managers may ask all applications simultaneously to commit their
- data, resulting in a much faster shutdown.
+ The rationale behind this mechanism is to make it possible to synchronize
+ user interaction during a shutdown. Advanced session managers may ask all
+ applications simultaneously to commit their data, resulting in a much
+ faster shutdown.
- When the interaction is completed we strongly recommend releasing the
- user interaction semaphore with a call to release(). This way, other
- applications may get the chance to interact with the user while your
- application is still busy saving data. (The semaphore is implicitly
- released when the application exits.)
+ When the interaction is completed we strongly recommend releasing the user
+ interaction semaphore with a call to release(). This way, other
+ applications may get the chance to interact with the user while your
+ application is still busy saving data. (The semaphore is implicitly
+ released when the application exits.)
- If the user decides to cancel the shutdown process during the
- interaction phase, you must tell the session manager that this has
- happened by calling cancel().
+ If the user decides to cancel the shutdown process during the interaction
+ phase, you must tell the session manager that this has happened by calling
+ cancel().
- Here's an example of how an application's QApplication::commitData()
- might be implemented:
+ Here's an example of how an application's QApplication::commitData() might
+ be implemented:
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 8
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 8
- If an error occurred within the application while saving its data,
- you may want to try allowsErrorInteraction() instead.
+ If an error occurred within the application while saving its data, you may
+ want to try allowsErrorInteraction() instead.
- \sa QApplication::commitData(), release(), cancel()
+ \sa QApplication::commitData(), release(), cancel()
*/
/*!
- \fn bool QSessionManager::allowsErrorInteraction()
+ \fn bool QSessionManager::allowsErrorInteraction()
- Returns true if error interaction is permitted; otherwise returns false.
+ Returns true if error interaction is permitted; otherwise returns false.
- This is similar to allowsInteraction(), but also enables the application
- to tell the user about any errors that occur. Session managers
- may give error interaction requests higher priority, which means that it
- is more likely that an error interaction is permitted. However, you are
- still not guaranteed that the session manager will allow interaction.
+ This is similar to allowsInteraction(), but also enables the application to
+ tell the user about any errors that occur. Session managers may give error
+ interaction requests higher priority, which means that it is more likely
+ that an error interaction is permitted. However, you are still not
+ guaranteed that the session manager will allow interaction.
- \sa allowsInteraction(), release(), cancel()
+ \sa allowsInteraction(), release(), cancel()
*/
/*!
- \fn void QSessionManager::release()
+ \fn void QSessionManager::release()
- Releases the session manager's interaction semaphore after an
- interaction phase.
+ Releases the session manager's interaction semaphore after an interaction
+ phase.
- \sa allowsInteraction(), allowsErrorInteraction()
+ \sa allowsInteraction(), allowsErrorInteraction()
*/
/*!
- \fn void QSessionManager::cancel()
-
- Tells the session manager to cancel the shutdown process. Applications
- should not call this function without first asking the user.
+ \fn void QSessionManager::cancel()
- \sa allowsInteraction(), allowsErrorInteraction()
+ Tells the session manager to cancel the shutdown process. Applications
+ should not call this function without asking the user first.
+ \sa allowsInteraction(), allowsErrorInteraction()
*/
/*!
- \fn void QSessionManager::setRestartHint(RestartHint hint)
+ \fn void QSessionManager::setRestartHint(RestartHint hint)
- Sets the application's restart hint to \a hint. On application
- startup the hint is set to \c RestartIfRunning.
+ Sets the application's restart hint to \a hint. On application startup, the
+ hint is set to \c RestartIfRunning.
- Note that these flags are only hints, a session manager may or may
- not respect them.
+ \note These flags are only hints, a session manager may or may not respect
+ them.
- We recommend setting the restart hint in QApplication::saveState()
- because most session managers perform a checkpoint shortly after an
- application's startup.
+ We recommend setting the restart hint in QApplication::saveState() because
+ most session managers perform a checkpoint shortly after an application's
+ startup.
- \sa restartHint()
+ \sa restartHint()
*/
/*!
- \fn QSessionManager::RestartHint QSessionManager::restartHint() const
+ \fn QSessionManager::RestartHint QSessionManager::restartHint() const
- Returns the application's current restart hint. The default is
- \c RestartIfRunning.
+ Returns the application's current restart hint. The default is
+ \c RestartIfRunning.
- \sa setRestartHint()
+ \sa setRestartHint()
*/
/*!
- \fn void QSessionManager::setRestartCommand(const QStringList& command)
+ \fn void QSessionManager::setRestartCommand(const QStringList& command)
- If the session manager is capable of restoring sessions it will
- execute \a command in order to restore the application. The command
- defaults to
+ If the session manager is capable of restoring sessions it will execute
+ \a command in order to restore the application. The command defaults to
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 9
- The \c -session option is mandatory; otherwise QApplication cannot
- tell whether it has been restored or what the current session
- identifier is. See QApplication::isSessionRestored() and
- QApplication::sessionId() for details.
+ The \c -session option is mandatory; otherwise QApplication cannot tell
+ whether it has been restored or what the current session identifier is.
+ See QApplication::isSessionRestored() and QApplication::sessionId() for
+ details.
- If your application is very simple, it may be possible to store the
- entire application state in additional command line options. This
- is usually a very bad idea because command lines are often limited
- to a few hundred bytes. Instead, use QSettings, or temporary files
- or a database for this purpose. By marking the data with the unique
- sessionId(), you will be able to restore the application in a future
- session.
+ If your application is very simple, it may be possible to store the entire
+ application state in additional command line options. This is usually a
+ very bad idea because command lines are often limited to a few hundred
+ bytes. Instead, use QSettings, temporary files, or a database for this
+ purpose. By marking the data with the unique sessionId(), you will be able
+ to restore the application in a future session.
- \sa restartCommand(), setDiscardCommand(), setRestartHint()
+ \sa restartCommand(), setDiscardCommand(), setRestartHint()
*/
/*!
@@ -4318,8 +4284,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
Returns the currently set restart command.
- To iterate over the list, you can use the \l foreach
- pseudo-keyword:
+ To iterate over the list, you can use the \l foreach pseudo-keyword:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 10
@@ -4327,11 +4292,11 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
*/
/*!
- \fn void QSessionManager::setDiscardCommand(const QStringList& list)
+ \fn void QSessionManager::setDiscardCommand(const QStringList& list)
- Sets the discard command to the given \a list.
+ Sets the discard command to the given \a list.
- \sa discardCommand(), setRestartCommand()
+ \sa discardCommand(), setRestartCommand()
*/
@@ -4340,8 +4305,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
Returns the currently set discard command.
- To iterate over the list, you can use the \l foreach
- pseudo-keyword:
+ To iterate over the list, you can use the \l foreach pseudo-keyword:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 11
@@ -4349,53 +4313,51 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
*/
/*!
- \fn void QSessionManager::setManagerProperty(const QString &name, const QString &value)
- \overload
+ \fn void QSessionManager::setManagerProperty(const QString &name, const QString &value)
+ \overload
- Low-level write access to the application's identification and state
- records are kept in the session manager.
+ Low-level write access to the application's identification and state
+ records are kept in the session manager.
- The property called \a name has its value set to the string \a value.
+ The property called \a name has its value set to the string \a value.
*/
/*!
- \fn void QSessionManager::setManagerProperty(const QString& name,
- const QStringList& value)
+ \fn void QSessionManager::setManagerProperty(const QString& name,
+ const QStringList& value)
- Low-level write access to the application's identification and state
- record are kept in the session manager.
+ Low-level write access to the application's identification and state record
+ are kept in the session manager.
- The property called \a name has its value set to the string list \a value.
+ The property called \a name has its value set to the string list \a value.
*/
/*!
- \fn bool QSessionManager::isPhase2() const
+ \fn bool QSessionManager::isPhase2() const
- Returns true if the session manager is currently performing a second
- session management phase; otherwise returns false.
+ Returns true if the session manager is currently performing a second
+ session management phase; otherwise returns false.
- \sa requestPhase2()
+ \sa requestPhase2()
*/
/*!
- \fn void QSessionManager::requestPhase2()
+ \fn void QSessionManager::requestPhase2()
- Requests a second session management phase for the application. The
- application may then return immediately from the
- QApplication::commitData() or QApplication::saveState() function,
- and they will be called again once most or all other applications have
- finished their session management.
+ Requests a second session management phase for the application. The
+ application may then return immediately from the QApplication::commitData()
+ or QApplication::saveState() function, and they will be called again once
+ most or all other applications have finished their session management.
- The two phases are useful for applications such as the X11 window manager
- that need to store information about another application's windows
- and therefore have to wait until these applications have completed their
- respective session management tasks.
+ The two phases are useful for applications such as the X11 window manager
+ that need to store information about another application's windows and
+ therefore have to wait until these applications have completed their
+ respective session management tasks.
- Note that if another application has requested a second phase it
- may get called before, simultaneously with, or after your
- application's second phase.
+ \note If another application has requested a second phase it may get called
+ before, simultaneously with, or after your application's second phase.
- \sa isPhase2()
+ \sa isPhase2()
*/
/*****************************************************************************
@@ -4588,15 +4550,14 @@ void QSessionManager::requestPhase2()
/*!
\fn bool QApplication::hasGlobalMouseTracking()
- This feature does not exist anymore. This function
- always returns true in Qt 4.
+ This feature does not exist anymore. This function always returns true
+ in Qt 4.
*/
/*!
\fn void QApplication::setGlobalMouseTracking(bool dummy)
- This function does nothing in Qt 4. The \a dummy parameter
- is ignored.
+ This function does nothing in Qt 4. The \a dummy parameter is ignored.
*/
/*!
@@ -4634,15 +4595,14 @@ void QSessionManager::requestPhase2()
/*!
\fn const QColor &QApplication::winStyleHighlightColor()
- Use qApp->palette().color(QPalette::Active, QPalette::Highlight)
- instead.
+ Use qApp->palette().color(QPalette::Active, QPalette::Highlight) instead.
*/
/*!
\fn QWidget *QApplication::widgetAt(int x, int y, bool child)
- Use the two-argument widgetAt() overload to get the child widget.
- To get the top-level widget do this:
+ Use the two-argument widgetAt() overload to get the child widget. To get
+ the top-level widget do this:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 12
*/
@@ -4650,8 +4610,8 @@ void QSessionManager::requestPhase2()
/*!
\fn QWidget *QApplication::widgetAt(const QPoint &point, bool child)
- Use the single-argument widgetAt() overload to get the child widget.
- To get the top-level widget do this:
+ Use the single-argument widgetAt() overload to get the child widget. To get
+ the top-level widget do this:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 13
*/
@@ -4723,10 +4683,9 @@ void QApplicationPrivate::emitLastWindowClosed()
Sets whether Qt should use focus navigation suitable for use with a
minimal keypad.
- If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to
- change focus.
+ If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus.
- This feature is only available in Qt for Embedded Linux.
+ This feature is available in Qt for Embedded Linux only.
\sa keypadNavigationEnabled()
*/
@@ -4739,7 +4698,8 @@ void QApplication::setKeypadNavigationEnabled(bool enable)
Returns true if Qt is set to use keypad navigation; otherwise returns
false. The default is false.
- This feature is only available in Qt for Embedded Linux.
+ This feature is available in Qt for Embedded Linux only.
+
\sa setKeypadNavigationEnabled()
*/
bool QApplication::keypadNavigationEnabled()
@@ -4762,12 +4722,12 @@ bool QApplication::keypadNavigationEnabled()
On Mac OS X, this works more at the application level and will cause the
application icon to bounce in the dock.
- On Windows this causes the window's taskbar entry to flash for a time. If \a
- msec is zero, the flashing will stop and the taskbar entry will turn a
+ On Windows this causes the window's taskbar entry to flash for a time. If
+ \a msec is zero, the flashing will stop and the taskbar entry will turn a
different color (currently orange).
- On X11, this will cause the window to be marked as "demands attention",
- the window must not be hidden (i.e. not have hide() called on it, but be
+ On X11, this will cause the window to be marked as "demands attention", the
+ window must not be hidden (i.e. not have hide() called on it, but be
visible in some sort of way) in order for this to work.
*/
@@ -4775,18 +4735,16 @@ bool QApplication::keypadNavigationEnabled()
\property QApplication::cursorFlashTime
\brief the text cursor's flash (blink) time in milliseconds
- The flash time is the time required to display, invert and
- restore the caret display. Usually the text cursor is displayed
- for half the cursor flash time, then hidden for the same amount
- of time, but this may vary.
+ The flash time is the time required to display, invert and restore the
+ caret display. Usually the text cursor is displayed for half the cursor
+ flash time, then hidden for the same amount of time, but this may vary.
- The default value on X11 is 1000 milliseconds. On Windows, the
- control panel value is used. Widgets should not cache this value
- since it may be changed at any time by the user changing the
- global desktop settings.
+ The default value on X11 is 1000 milliseconds. On Windows, the control
+ panel value is used. Widgets should not cache this value since it may be
+ changed at any time by the user changing the global desktop settings.
- Note that on Microsoft Windows, setting this property sets the
- cursor flash time for all applications.
+ \note On Microsoft Windows, setting this property sets the cursor flash
+ time for all applications.
*/
/*!
@@ -4794,11 +4752,11 @@ bool QApplication::keypadNavigationEnabled()
\brief the time limit in milliseconds that distinguishes a double click from two
consecutive mouse clicks
- The default value on X11 is 400 milliseconds. On Windows and Mac
- OS X, the operating system's value is used.
+ The default value on X11 is 400 milliseconds. On Windows and Mac OS X, the
+ operating system's value is used.
- On Microsoft Windows, calling this function sets the
- double click interval for all applications.
+ On Microsoft Windows, calling this function sets the double click interval
+ for all applications.
*/
/*!
@@ -4816,15 +4774,13 @@ bool QApplication::keypadNavigationEnabled()
\brief the number of lines to scroll a widget, when the
mouse wheel is rotated.
- If the value exceeds the widget's number of visible lines, the
- widget should interpret the scroll operation as a single \e{page
- up} or \e{page down}. If the widget is an \l{QAbstractItemView}
- {item view class}, then the result of scrolling one \e line
- depends on the setting of the widget's
- \l{QAbstractItemView::verticalScrollMode()} {scroll mode}. Scroll
- one \e line can mean \l{QAbstractItemView::ScrollPerItem} {scroll
- one item} or \l{QAbstractItemView::ScrollPerPixel} {scroll one
- pixel}.
+ If the value exceeds the widget's number of visible lines, the widget
+ should interpret the scroll operation as a single \e{page up} or
+ \e{page down}. If the widget is an \l{QAbstractItemView}{item view class},
+ then the result of scrolling one \e line depends on the setting of the
+ widget's \l{QAbstractItemView::verticalScrollMode()}{scroll mode}. Scroll
+ one \e line can mean \l{QAbstractItemView::ScrollPerItem}{scroll one item}
+ or \l{QAbstractItemView::ScrollPerPixel}{scroll one pixel}.
By default, this property has a value of 3.
*/
@@ -4832,11 +4788,11 @@ bool QApplication::keypadNavigationEnabled()
/*!
\fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
- Enables the UI effect \a effect if \a enable is true, otherwise
- the effect will not be used.
+ Enables the UI effect \a effect if \a enable is true, otherwise the effect
+ will not be used.
- Note: All effects are disabled on screens running at less than
- 16-bit color depth.
+ \note All effects are disabled on screens running at less than 16-bit color
+ depth.
\sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
*/
@@ -4846,11 +4802,11 @@ bool QApplication::keypadNavigationEnabled()
Returns true if \a effect is enabled; otherwise returns false.
- By default, Qt will try to use the desktop settings. Call
- setDesktopSettingsAware(false) to prevent this.
+ By default, Qt will try to use the desktop settings. To prevent this, call
+ setDesktopSettingsAware(false).
- Note: All effects are disabled on screens running at less than
- 16-bit color depth.
+ \note All effects are disabled on screens running at less than 16-bit color
+ depth.
\sa setEffectEnabled(), Qt::UIEffect
*/
@@ -4858,8 +4814,7 @@ bool QApplication::keypadNavigationEnabled()
/*!
\fn QWidget *QApplication::mainWidget()
- Returns the main application widget, or 0 if there is no main
- widget.
+ Returns the main application widget, or 0 if there is no main widget.
*/
/*!
@@ -4867,19 +4822,17 @@ bool QApplication::keypadNavigationEnabled()
Sets the application's main widget to \a mainWidget.
- In most respects the main widget is like any other widget, except
- that if it is closed, the application exits. Note that
- QApplication does \e not take ownership of the \a mainWidget, so
- if you create your main widget on the heap you must delete it
- yourself.
+ In most respects the main widget is like any other widget, except that if
+ it is closed, the application exits. QApplication does \e not take
+ ownership of the \a mainWidget, so if you create your main widget on the
+ heap you must delete it yourself.
- You need not have a main widget; connecting lastWindowClosed() to
- quit() is an alternative.
+ You need not have a main widget; connecting lastWindowClosed() to quit()
+ is an alternative.
- For X11, this function also resizes and moves the main widget
- according to the \e -geometry command-line option, so you should
- set the default geometry (using \l QWidget::setGeometry()) before
- calling setMainWidget().
+ For X11, this function also resizes and moves the main widget according
+ to the \e -geometry command-line option, so you should set the default
+ geometry (using \l QWidget::setGeometry()) before calling setMainWidget().
\sa mainWidget(), exec(), quit()
*/
@@ -4887,8 +4840,8 @@ bool QApplication::keypadNavigationEnabled()
/*!
\fn void QApplication::beep()
- Sounds the bell, using the default volume and sound. The function
- is \e not available in Qt for Embedded Linux.
+ Sounds the bell, using the default volume and sound. The function is \e not
+ available in Qt for Embedded Linux.
*/
/*!
@@ -4896,26 +4849,25 @@ bool QApplication::keypadNavigationEnabled()
Sets the application override cursor to \a cursor.
- Application override cursors are intended for showing the user
- that the application is in a special state, for example during an
- operation that might take some time.
+ Application override cursors are intended for showing the user that the
+ application is in a special state, for example during an operation that
+ might take some time.
- This cursor will be displayed in all the application's widgets
- until restoreOverrideCursor() or another setOverrideCursor() is
- called.
+ This cursor will be displayed in all the application's widgets until
+ restoreOverrideCursor() or another setOverrideCursor() is called.
- Application cursors are stored on an internal stack.
- setOverrideCursor() pushes the cursor onto the stack, and
- restoreOverrideCursor() pops the active cursor off the
- stack. changeOverrideCursor() changes the curently active
- application override cursor. Every setOverrideCursor() must
+ Application cursors are stored on an internal stack. setOverrideCursor()
+ pushes the cursor onto the stack, and restoreOverrideCursor() pops the
+ active cursor off the stack. changeOverrideCursor() changes the curently
+ active application override cursor. Every setOverrideCursor() must
eventually be followed by a corresponding restoreOverrideCursor(),
otherwise the stack will never be emptied.
Example:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp 0
- \sa overrideCursor() restoreOverrideCursor() changeOverrideCursor() QWidget::setCursor()
+ \sa overrideCursor(), restoreOverrideCursor(), changeOverrideCursor(),
+ QWidget::setCursor()
*/
/*!
@@ -4924,9 +4876,8 @@ bool QApplication::keypadNavigationEnabled()
Undoes the last setOverrideCursor().
If setOverrideCursor() has been called twice, calling
- restoreOverrideCursor() will activate the first cursor set.
- Calling this function a second time restores the original widgets'
- cursors.
+ restoreOverrideCursor() will activate the first cursor set. Calling this
+ function a second time restores the original widgets' cursors.
\sa setOverrideCursor(), overrideCursor()
*/
@@ -4936,9 +4887,9 @@ bool QApplication::keypadNavigationEnabled()
\relates QApplication
A global pointer referring to the unique application object. It is
- equivalent to the pointer returned by the
- QCoreApplication::instance() function except that, in GUI applications,
- it is a pointer to a QApplication instance.
+ equivalent to the pointer returned by the QCoreApplication::instance()
+ function except that, in GUI applications, it is a pointer to a
+ QApplication instance.
Only one application object can be created.
@@ -4950,8 +4901,8 @@ bool QApplication::keypadNavigationEnabled()
// ************************************************************************
/*!
- This function replaces the QInputContext instance used by the
- application with \a inputContext.
+ This function replaces the QInputContext instance used by the application
+ with \a inputContext.
\sa inputContext()
*/
@@ -4982,7 +4933,11 @@ QInputContext *QApplication::inputContext() const
return 0;
if (!d->inputContext) {
QApplication *that = const_cast<QApplication *>(this);
- that->d_func()->inputContext = QInputContextFactory::create(X11->default_im, that);
+ QInputContext *qic = QInputContextFactory::create(X11->default_im, that);
+ // fallback to default X Input Method.
+ if (!qic)
+ qic = QInputContextFactory::create(QLatin1String("xim"), that);
+ that->d_func()->inputContext = qic;
}
#endif
return d->inputContext;
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 1df442f..b1270bc 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -829,8 +829,11 @@ bool QApplicationPrivate::x11_apply_settings()
QColor(strlist[i]));
}
- if (groupCount == QPalette::NColorGroups)
- QApplicationPrivate::setSystemPalette(pal);
+ // ### Fix properly for 4.6
+ if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) {
+ if (groupCount == QPalette::NColorGroups)
+ QApplicationPrivate::setSystemPalette(pal);
+ }
int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
@@ -887,11 +890,15 @@ bool QApplicationPrivate::x11_apply_settings()
}
}
+ static QString currentStyleName = stylename;
if (QCoreApplication::startingUp()) {
if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride)
QApplicationPrivate::styleOverride = new QString(stylename);
} else {
- QApplication::setStyle(stylename);
+ if (currentStyleName != stylename) {
+ currentStyleName = stylename;
+ QApplication::setStyle(stylename);
+ }
}
int num =
@@ -1355,8 +1362,10 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
}
- QApplicationPrivate::setSystemPalette(pal);
-
+ // QGtkStyle sets it's own system palette
+ if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) {
+ QApplicationPrivate::setSystemPalette(pal);
+ }
QColor::setAllowX11ColorNames(allowX11ColorNames);
}
@@ -3351,15 +3360,24 @@ int QApplication::x11ProcessEvent(XEvent* event)
// update the size for desktop widget
int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window);
- QWidget *w = desktop()->screen(scr);
+ QDesktopWidget *desktop = QApplication::desktop();
+ QWidget *w = desktop->screen(scr);
QSize oldSize(w->size());
w->data->crect.setWidth(DisplayWidth(X11->display, scr));
w->data->crect.setHeight(DisplayHeight(X11->display, scr));
- if (w->size() != oldSize) {
- QResizeEvent e(w->size(), oldSize);
- QApplication::sendEvent(w, &e);
- emit desktop()->resized(scr);
- }
+ QVarLengthArray<QRect> oldSizes(desktop->numScreens());
+ for (int i = 0; i < desktop->numScreens(); ++i)
+ oldSizes[i] = desktop->screenGeometry(i);
+ QResizeEvent e(w->size(), oldSize);
+ QApplication::sendEvent(w, &e);
+ for (int i = 0; i < qMin(oldSizes.count(), desktop->numScreens()); ++i) {
+ if (oldSizes[i] != desktop->screenGeometry(i))
+ emit desktop->resized(i);
+ }
+ for (int i = oldSizes.count(); i < desktop->numScreens(); ++i)
+ emit desktop->resized(i); // added
+ for (int i = desktop->numScreens(); i < oldSizes.count(); ++i)
+ emit desktop->resized(i); // removed
}
#endif // QT_NO_XRANDR
diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm
index f95f004f..a3cc2c1 100644
--- a/src/gui/kernel/qcocoaapplication_mac.mm
+++ b/src/gui/kernel/qcocoaapplication_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
/****************************************************************************
**
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
index 650ebbd..6571068 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
/****************************************************************************
**
@@ -107,6 +107,8 @@ static void cleanupCocoaApplicationDelegate()
- (id)init
{
self = [super init];
+ if (self)
+ inLaunch = true;
return self;
}
@@ -198,12 +200,26 @@ static void cleanupCocoaApplicationDelegate()
return reply;
}
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ Q_UNUSED(aNotification);
+ inLaunch = false;
+}
+
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
- unsigned int ix;
- for( ix = 0; ix < [filenames count]; ix++) {
- NSString *fileName = [filenames objectAtIndex:ix];
- qApp->postEvent(qApp, new QFileOpenEvent(QCFString::toQString((CFStringRef)fileName)));
+ for (NSString *fileName in filenames) {
+ QString qtFileName = qt_mac_NSStringToQString(fileName);
+ if (inLaunch) {
+ // We need to be careful because Cocoa will be nice enough to take
+ // command line arguments and send them to us as events. Given the history
+ // of Qt Applications, this will result in behavior people don't want, as
+ // they might be doing the opening themselves with the command line parsing.
+ if (qApp->arguments().contains(qtFileName))
+ continue;
+ }
+ QFileOpenEvent foe(qtFileName);
+ qt_sendSpontaneousEvent(qAppInstance(), &foe);
}
if (reflectionDelegate &&
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
index c5336f1..fca2a15 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
@@ -107,6 +107,7 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
NSMenu *dockMenu;
QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader;
id <NSApplicationDelegate> reflectionDelegate;
+ bool inLaunch;
}
+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
- (void)setDockMenu:(NSMenu *)newMenu;
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
index 7ecb765..e836286 100644
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ b/src/gui/kernel/qcocoamenuloader_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#include "qmacdefines_mac.h"
#ifdef QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index 6aeee34..c69826f 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -43,10 +43,16 @@
#ifdef QT_MAC_USE_COCOA
#import <private/qt_cocoa_helpers_mac_p.h>
#import <private/qcocoawindow_mac_p.h>
+#import <private/qcocoawindowdelegate_mac_p.h>
+#import <private/qcocoaview_mac_p.h>
#import <private/qcocoawindowcustomthemeframe_mac_p.h>
#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
@implementation QT_MANGLE_NAMESPACE(QCocoaPanel)
@@ -60,18 +66,115 @@ QT_USE_NAMESPACE
return !(isPopup || isToolTip);
}
+/***********************************************************************
+ BEGIN 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)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
{
[self retain];
- [super sendEvent:event];
+
+ QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+ 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 [QCocoaWindowCustomThemeFrame class];
+ 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 df42e79..e84af90 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -181,6 +181,7 @@ QT_FORWARD_DECLARE_CLASS(QAbstractScrollAreaPrivate)
QT_FORWARD_DECLARE_CLASS(QPaintEvent)
QT_FORWARD_DECLARE_CLASS(QPainter)
QT_FORWARD_DECLARE_CLASS(QHoverEvent)
+QT_FORWARD_DECLARE_CLASS(QCursor)
QT_USE_NAMESPACE
extern "C" {
extern NSString *NSTextInputReplacementRangeAttributeName;
@@ -236,6 +237,34 @@ extern "C" {
}
}
+- (void)resetCursorRects
+{
+ QWidget *cursorWidget = qwidget;
+
+ if (cursorWidget->testAttribute(Qt::WA_TransparentForMouseEvents))
+ cursorWidget = QApplication::widgetAt(qwidget->mapToGlobal(qwidget->rect().center()));
+
+ if (cursorWidget == 0)
+ return;
+
+ if (!cursorWidget->testAttribute(Qt::WA_SetCursor)) {
+ [super resetCursorRects];
+ return;
+ }
+
+ QRegion mask = qt_widget_private(cursorWidget)->extra->mask;
+ NSCursor *nscursor = static_cast<NSCursor *>(nsCursorForQCursor(cursorWidget->cursor()));
+ if (mask.isEmpty()) {
+ [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor];
+ } else {
+ const QVector<QRect> &rects = mask.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect &rect = rects.at(i);
+ [self addCursorRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()) cursor:nscursor];
+ }
+ }
+}
+
- (void)removeDropData
{
if (dropData) {
@@ -300,11 +329,13 @@ extern "C" {
NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
+ NSDragOperation nsActions = [sender draggingSourceOperationMask];
QPoint posDrag(localPoint.x, localPoint.y);
- if (qt_mac_mouse_inside_answer_rect(posDrag))
+ if (qt_mac_mouse_inside_answer_rect(posDrag)
+ && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions)
return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
// send drag move event to the widget
- NSDragOperation nsActions = [sender draggingSourceOperationMask];
+ QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
QMimeData *mimeData = dropData;
if (QDragManager::self()->source())
@@ -599,7 +630,7 @@ extern "C" {
for (NSView *lookView in viewsToLookAt) {
NSPoint tmpPoint = [lookView convertPoint:windowPoint fromView:nil];
for (NSView *view in [lookView subviews]) {
- if (view == mouseView)
+ if (view == mouseView || [view isHidden])
continue;
NSRect frameRect = [view frame];
if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
@@ -618,7 +649,7 @@ extern "C" {
NSPoint tmpPoint = [viewForDescent convertPoint:windowPoint fromView:nil];
// Apply same rule as above wrt z-order.
for (NSView *view in [viewForDescent subviews]) {
- if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
+ if (![view isHidden] && NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
lowerView = view;
}
if (!lowerView) // Low as we can be at this point.
@@ -887,15 +918,18 @@ extern "C" {
QWidget *widgetToGetKey = qwidget;
QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != qwidget->window())
+ bool sendToPopup = false;
+ if (popup && popup != qwidget->window()) {
widgetToGetKey = popup->focusWidget() ? popup->focusWidget() : popup;
+ sendToPopup = true;
+ }
if (widgetToGetKey->testAttribute(Qt::WA_InputMethodEnabled)) {
[qt_mac_nativeview_for(widgetToGetKey) interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
}
if (sendKeyEvents && !composing) {
bool keyOK = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
- if (!keyOK)
+ if (!keyOK && !sendToPopup)
[super keyDown:theEvent];
}
}
@@ -910,6 +944,27 @@ extern "C" {
}
}
+- (void)viewWillMoveToWindow:(NSWindow *)window
+{
+ if (qwidget->windowFlags() & Qt::MSWindowsOwnDC
+ && (window != [self window])) { // OpenGL Widget
+ // Create a stupid ClearDrawable Event
+ QEvent event(QEvent::MacGLClearDrawable);
+ qApp->sendEvent(qwidget, &event);
+ }
+}
+
+- (void)viewDidMoveToWindow
+{
+ if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) {
+ // call update paint event
+ qwidgetprivate->needWindowChange = true;
+ QEvent event(QEvent::MacGLWindowChange);
+ qApp->sendEvent(qwidget, &event);
+ }
+}
+
+
// NSTextInput Protocol implementation
- (void) insertText:(id)aString
diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm
index 6b30444..89f481f 100644
--- a/src/gui/kernel/qcocoawindow_mac.mm
+++ b/src/gui/kernel/qcocoawindow_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#include "qmacdefines_mac.h"
#ifdef QT_MAC_USE_COCOA
@@ -53,9 +53,10 @@
#include <QtGui/QWidget>
QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_USE_NAMESPACE
-
+QT_BEGIN_NAMESPACE
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
+QT_END_NAMESPACE
+QT_USE_NAMESPACE
@implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration))
@@ -86,6 +87,12 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.
return YES;
}
+/***********************************************************************
+ BEGIN 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.
@@ -124,7 +131,7 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.
[self retain];
QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
- QCocoaView *view = static_cast<QCocoaView *>(qt_mac_nativeview_for(widget));
+ 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.
@@ -173,6 +180,20 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.
[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)
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm
index 8cd97b9..03b2fce 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#import "private/qcocoawindowdelegate_mac_p.h"
#ifdef QT_MAC_USE_COCOA
@@ -266,18 +266,18 @@ static void cleanupCocoaWindowDelegate()
-(void)windowDidBecomeMain:(NSNotification*)notification
{
- NSWindow *window = [notification object];
- if ([window isKeyWindow])
- return; // Should have already got an activate notification from "become key."
-
QWidget *qwidget = m_windowHash->value([notification object]);
+ Q_ASSERT(qwidget);
+ if (qwidget->isActiveWindow())
+ return; // Widget is already active, no need to go through re-activation.
+
onApplicationWindowChangedActivation(qwidget, true);
}
-(void)windowDidResignMain:(NSNotification*)notification
{
QWidget *qwidget = m_windowHash->value([notification object]);
-
+ Q_ASSERT(qwidget);
onApplicationWindowChangedActivation(qwidget, false);
}
@@ -285,11 +285,11 @@ static void cleanupCocoaWindowDelegate()
// tiny difference between main and key windows.
-(void)windowDidBecomeKey:(NSNotification*)notification
{
- NSWindow *window = [notification object];
- if ([window isMainWindow])
- return; // Should have already got an activate notification from "become main."
+ QWidget *qwidget = m_windowHash->value([notification object]);
+ Q_ASSERT(qwidget);
+ if (qwidget->isActiveWindow())
+ return; // Widget is already active, no need to go through re-activation
- QWidget *qwidget = m_windowHash->value(window);
onApplicationWindowChangedActivation(qwidget, true);
}
@@ -297,6 +297,7 @@ static void cleanupCocoaWindowDelegate()
-(void)windowDidResignKey:(NSNotification*)notification
{
QWidget *qwidget = m_windowHash->value([notification object]);
+ Q_ASSERT(qwidget);
onApplicationWindowChangedActivation(qwidget, false);
}
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index 15b4597..ad1860d 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -77,6 +77,7 @@ class QBitmap;
class QPixmap;
#if defined(Q_WS_MAC)
+void *nsCursorForQCursor(const QCursor &c);
void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
@@ -128,6 +129,7 @@ public:
private:
QCursorData *d;
#if defined(Q_WS_MAC)
+ friend void *nsCursorForQCursor(const QCursor &c);
friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p);
#endif
};
diff --git a/src/gui/kernel/qcursor_mac.mm b/src/gui/kernel/qcursor_mac.mm
index d632eb79..ae98f2e 100644
--- a/src/gui/kernel/qcursor_mac.mm
+++ b/src/gui/kernel/qcursor_mac.mm
@@ -95,9 +95,19 @@ protected:
}
};
+void *nsCursorForQCursor(const QCursor &c)
+{
+ c.d->update();
+ return [[static_cast<NSCursor *>(c.d->curs.cp.nscursor) retain] autorelease];
+}
+
static QCursorData *currentCursor = 0; //current cursor
void qt_mac_set_cursor(const QCursor *c, const QPoint &)
{
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(c);
+ return;
+#else
if (!c) {
currentCursor = 0;
return;
@@ -128,10 +138,15 @@ void qt_mac_set_cursor(const QCursor *c, const QPoint &)
}
}
currentCursor = c->d;
+#endif
}
void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos)
{
+#ifdef QT_MAC_USE_COCOA
+ Q_UNUSED(globalPos);
+ return;
+#else
QCursor cursor(Qt::ArrowCursor);
if (QApplication::overrideCursor()) {
cursor = *QApplication::overrideCursor();
@@ -144,6 +159,7 @@ void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos)
}
}
qt_mac_set_cursor(&cursor, globalPos);
+#endif
}
void qt_mac_update_cursor()
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 3f1df5e..8c7e47d 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -1656,7 +1656,7 @@ Qt::ButtonState QContextMenuEvent::state() const
The variant contains a QLocale object specifying the language of a
certain part of the preedit string. There should be at most one
language set for every part of the preedit string. If several are
- specified for any character in the string the behaviour is undefined.
+ specified for any character in the string the behavior is undefined.
\value Ruby
The ruby text for a part of the preedit string. There should be at
diff --git a/src/gui/kernel/qmacdefines_mac.h b/src/gui/kernel/qmacdefines_mac.h
index 97ec544..035b8c5 100644
--- a/src/gui/kernel/qmacdefines_mac.h
+++ b/src/gui/kernel/qmacdefines_mac.h
@@ -105,7 +105,7 @@ Yes, it is an informative comment ;-)
# undef qDebug
#endif
-#if __LP64__
+#ifdef __LP64__
typedef signed int OSStatus;
#else
typedef signed long OSStatus;
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 9c381b4..52e76d8 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -555,12 +555,15 @@ bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widge
int keyLength = [keyChars length];
if (keyLength == 0)
return false; // Dead Key, nothing to do!
+ bool ignoreText = false;
Qt::Key qtKey = Qt::Key_unknown;
if (keyLength == 1) {
QChar ch([keyChars characterAtIndex:0]);
if (ch.isLower())
ch = ch.toUpper();
qtKey = cocoaKey2QtKey(ch);
+ // Do not set the text for Function-Key Unicodes characters (0xF700–0xF8FF).
+ ignoreText = (ch.unicode() >= 0xF700 && ch.unicode() <= 0xF8FF);
}
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
QString text;
@@ -568,7 +571,7 @@ bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widge
// To quote from the Carbon port: This is actually wrong--but it is the best that
// can be done for now because of the Control/Meta mapping issues
// (we always get text on the Mac)
- if (!(keyMods & (Qt::ControlModifier | Qt::MetaModifier)))
+ if (!ignoreText && !(keyMods & (Qt::ControlModifier | Qt::MetaModifier)))
text = QCFString::toQString(reinterpret_cast<CFStringRef>(keyChars));
UInt32 macScanCode = 1;
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index b462b13..b1247e8 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -93,6 +93,8 @@ static QColor qcolorFromCGColor(CGColorRef cgcolor)
pc.setRgbF(components[0], components[1], components[2], components[3]);
} else if (model == kCGColorSpaceModelCMYK) {
pc.setCmykF(components[0], components[1], components[2], components[3]);
+ } else if (model == kCGColorSpaceModelMonochrome) {
+ pc.setRgbF(components[0], components[0], components[0], components[1]);
} else {
// Colorspace we can't deal with.
qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model);
@@ -129,16 +131,47 @@ QColor qcolorForTheme(ThemeBrush brush)
QColor qcolorForThemeTextColor(ThemeTextColor themeColor)
{
-#ifndef QT_MAC_USE_COCOA
+#ifdef QT_OS_MAC32
RGBColor c;
GetThemeTextColor(themeColor, 32, true, &c);
- return QColor(c.red / 265, c.green / 256, c.blue / 256);
+ QColor color = QColor(c.red / 265, c.green / 256, c.blue / 256);
+ return color;
#else
- QNativeImage nativeImage(16,16, QNativeImage::systemFormat());
- CGRect cgrect = CGRectMake(0, 0, 16, 16);
- HIThemeSetTextFill(themeColor, 0, nativeImage.cg, kHIThemeOrientationNormal);
- CGContextFillRect(nativeImage.cg, cgrect);
- return QColor(nativeImage.image.pixel(0 , 0));
+ // There is no equivalent to GetThemeTextColor in 64-bit and it was rather bad that
+ // I didn't file a request to implement this for Snow Leopard. So, in the meantime
+ // I've encoded the values from the GetThemeTextColor. This is not exactly ideal
+ // as if someone really wants to mess with themeing, these colors will be wrong.
+ // It also means that we need to make sure the values for differences between
+ // OS releases (and it will be likely that we are a step behind.)
+ switch (themeColor) {
+ case kThemeTextColorAlertActive:
+ case kThemeTextColorTabFrontActive:
+ case kThemeTextColorBevelButtonActive:
+ case kThemeTextColorListView:
+ case kThemeTextColorPlacardActive:
+ case kThemeTextColorPopupButtonActive:
+ case kThemeTextColorPopupLabelActive:
+ case kThemeTextColorPushButtonActive:
+ return Qt::black;
+ case kThemeTextColorAlertInactive:
+ case kThemeTextColorDialogInactive:
+ case kThemeTextColorPlacardInactive:
+ return QColor(67, 69, 69, 255);
+ case kThemeTextColorPopupButtonInactive:
+ case kThemeTextColorPopupLabelInactive:
+ case kThemeTextColorPushButtonInactive:
+ case kThemeTextColorTabFrontInactive:
+ case kThemeTextColorBevelButtonInactive:
+ return QColor(123, 127, 127, 255);
+ default: {
+ QNativeImage nativeImage(16,16, QNativeImage::systemFormat());
+ CGRect cgrect = CGRectMake(0, 0, 16, 16);
+ HIThemeSetTextFill(themeColor, 0, nativeImage.cg, kHIThemeOrientationNormal);
+ CGContextFillRect(nativeImage.cg, cgrect);
+ QColor color = nativeImage.image.pixel(0,0);
+ return QColor(nativeImage.image.pixel(0 , 0));
+ }
+ }
#endif
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h
index 3aec23f..ca995dc 100644
--- a/src/gui/kernel/qt_mac_p.h
+++ b/src/gui/kernel/qt_mac_p.h
@@ -233,6 +233,7 @@ extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp
extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.mm
extern OSViewRef qt_mac_nativeview_for(const QWidget *); //qwidget_mac.mm
+extern QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt); //qwidget_mac.mm
#ifdef check
# undef check
@@ -249,11 +250,13 @@ struct QMacDndAnswerRecord {
Qt::KeyboardModifiers modifiers;
Qt::MouseButtons buttons;
Qt::DropAction lastAction;
+ unsigned int lastOperation;
void clear() {
rect = QRect();
modifiers = Qt::NoModifier;
buttons = Qt::NoButton;
lastAction = Qt::IgnoreAction;
+ lastOperation = 0;
}
};
extern QMacDndAnswerRecord qt_mac_dnd_answer_rec;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 63d31b5..31fed5e 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -66,6 +66,7 @@
#ifdef Q_WS_MAC
# include "qt_mac_p.h"
# include "qt_cocoa_helpers_mac_p.h"
+# include "qmainwindow.h"
#endif
#if defined(Q_WS_QWS)
# include "qwsdisplay_qws.h"
@@ -164,6 +165,7 @@ static inline bool bypassGraphicsProxyWidget(QWidget *p)
#endif
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
+extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
QWidgetPrivate::QWidgetPrivate(int version) :
QObjectPrivate(version), extra(0), focus_child(0)
@@ -234,28 +236,6 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
/*!
\internal
- This is an internal function, you should never call this.
-
- This function is called to focus associated input context. The
- code intends to eliminate duplicate focus for the context even if
- the context is shared between widgets
-
- \sa QInputContext::setFocus()
- */
-void QWidgetPrivate::focusInputContext()
-{
-#ifndef QT_NO_IM
- Q_Q(QWidget);
- QInputContext *qic = q->inputContext();
- if (qic) {
- if(qic->focusWidget() != q)
- qic->setFocusWidget(q);
- }
-#endif // QT_NO_IM
-}
-
-/*!
- \internal
*/
void QWidgetPrivate::scrollChildren(int dx, int dy)
{
@@ -329,20 +309,24 @@ void QWidget::setInputContext(QInputContext *context)
/*!
+ \obsolete
+
This function can be called on the widget that currently has focus
to reset the input method operating on it.
- \sa QInputContext, QInputContext::reset()
+ This function is providing for convenience, instead you should use
+ \l{QInputContext::}{reset()} on the input context that was
+ returned by inputContext().
+
+ \sa QInputContext, inputContext(), QInputContext::reset()
*/
void QWidget::resetInputContext()
{
if (!hasFocus())
return;
#ifndef QT_NO_IM
- if (!d_func()->ic)
- return;
QInputContext *qic = this->inputContext();
- if( qic )
+ if(qic)
qic->reset();
#endif // QT_NO_IM
}
@@ -1400,7 +1384,13 @@ int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
void QWidgetPrivate::setWinId(WId id) // set widget identifier
{
Q_Q(QWidget);
- if (mapper && data.winid) {
+ // the user might create a widget with Qt::Desktop window
+ // attribute (or create another QDesktopWidget instance), which
+ // will have the same windowid (the root window id) as the
+ // qt_desktopWidget. We should not add the second desktop widget
+ // to the mapper.
+ bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop;
+ if (mapper && data.winid && !userDesktopWidget) {
mapper->remove(data.winid);
uncreatedWidgets->insert(q);
}
@@ -1409,7 +1399,7 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier
#if defined(Q_WS_X11)
hd = id; // X11: hd == ident
#endif
- if (mapper && id) {
+ if (mapper && id && !userDesktopWidget) {
mapper->insert(data.winid, q);
uncreatedWidgets->remove(q);
}
@@ -4653,6 +4643,8 @@ void QWidget::unsetCursor()
*/
/*!
+ \since 4.3
+
Renders the \a sourceRegion of this widget into the \a target
using \a renderFlags to determine how to render. Rendering
starts at \a targetOffset in the \a target. For example:
@@ -4662,12 +4654,13 @@ void QWidget::unsetCursor()
If \a sourceRegion is a null region, this function will use QWidget::rect() as
the region, i.e. the entire widget.
- \bold{Note:} Make sure to call QPainter::end() for the given \a target's
+ Ensure that you call QPainter::end() for the \a target device's
active painter (if any) before rendering. For example:
\snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 8
- \since 4.3
+ \note To obtain the contents of an OpenGL widget, use QGLWidget::grabFrameBuffer()
+ or QGLWidget::renderPixmap() instead.
*/
void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, RenderFlags renderFlags)
@@ -5928,12 +5921,12 @@ bool QWidget::isActiveWindow() const
return true;
#endif
if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
- if(((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
+ if(tlw->windowType() == Qt::Tool &&
!tlw->isModal() &&
(!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
return true;
QWidget *w = qApp->activeWindow();
- while(w && ((tlw->windowType() == Qt::Dialog) || (tlw->windowType() == Qt::Tool)) &&
+ while(w && tlw->windowType() == Qt::Tool &&
!w->isModal() && w->parentWidget()) {
w = w->parentWidget()->window();
if(w == tlw)
@@ -8974,17 +8967,36 @@ QWidget *QWidget::childAt(const QPoint &p) const
QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
{
Q_Q(const QWidget);
- if (!q->rect().contains(p))
+#ifdef Q_WS_MAC
+ bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q)
+ && static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac();
+#endif
+
+ if (
+#ifdef Q_WS_MAC
+ !includeFrame &&
+#endif
+ !q->rect().contains(p))
return 0;
+
for (int i = children.size(); i > 0 ;) {
--i;
QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->isWindow() && !w->isHidden() && w->geometry().contains(p)) {
+ if (w && !w->isWindow() && !w->isHidden()
+ && (w->geometry().contains(p)
+#ifdef Q_WS_MAC
+ || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p)))
+#endif
+ )) {
if (ignoreChildrenInDestructor && w->data->in_destructor)
continue;
if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
continue;
QPoint childPoint = w->mapFromParent(p);
+#ifdef Q_WS_MAC
+ if (includeFrame && !w->geometry().contains(p))
+ childPoint = qt_mac_nativeMapFromParent(w, p);
+#endif
if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor))
return t;
// if WMouseNoMask is set the widget mask is ignored, if
@@ -9425,11 +9437,13 @@ void QWidget::repaint(const QRect &rect)
if (!isVisible() || !updatesEnabled() || rect.isEmpty())
return;
- QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0;
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStore->markDirty(rect, this, true);
- tlwExtra->inRepaint = false;
+ if (hasBackingStoreSupport()) {
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStore->markDirty(rect, this, true);
+ tlwExtra->inRepaint = false;
+ }
} else {
d->repaint_sys(rect);
}
@@ -9452,11 +9466,13 @@ void QWidget::repaint(const QRegion &rgn)
if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
return;
- QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0;
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
- tlwExtra->inRepaint = true;
- tlwExtra->backingStore->markDirty(rgn, this, true);
- tlwExtra->inRepaint = false;
+ if (hasBackingStoreSupport()) {
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStore->markDirty(rgn, this, true);
+ tlwExtra->inRepaint = false;
+ }
} else {
d->repaint_sys(rgn);
}
@@ -9638,7 +9654,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
"QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
#ifdef Q_WS_WIN
- if (attribute == Qt::WA_PaintOnScreen) {
+ if (attribute == Qt::WA_PaintOnScreen && on) {
// see qwidget_win.cpp, ::paintEngine for details
paintEngine();
if (d->noPaintOnScreen)
@@ -9783,12 +9799,21 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
break;
#endif
- case Qt::WA_NativeWindow:
+ case Qt::WA_NativeWindow: {
+ QInputContext *ic = 0;
+ if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
+ ic = d->inputContext();
+ ic->reset();
+ ic->setFocusWidget(0);
+ }
if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
parentWidget()->d_func()->enforceNativeChildren();
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
d->createWinId();
+ if (ic)
+ ic->setFocusWidget(this);
break;
+ }
case Qt::WA_PaintOnScreen:
d->updateIsOpaque();
#if defined(Q_WS_WIN) || defined(Q_WS_X11)
@@ -11268,7 +11293,7 @@ QT_END_NAMESPACE
currently the active one then it will not make it the active
window. It will change the color of the taskbar entry to indicate
that the window has changed in some way. This is because Microsoft
- do not allow an application to interrupt what the user is currently
+ does not allow an application to interrupt what the user is currently
doing in another application.
\sa isActiveWindow(), window(), show()
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 7cceb4f..2c3f7f1 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -295,9 +295,7 @@ bool qt_mac_is_macsheet(const QWidget *w)
Qt::WindowModality modality = w->windowModality();
if (modality == Qt::ApplicationModal)
return false;
- if (modality == Qt::WindowModal || w->windowType() == Qt::Sheet)
- return true;
- return false;
+ return w->parentWidget() && (modality == Qt::WindowModal || w->windowType() == Qt::Sheet);
}
bool qt_mac_is_macdrawer(const QWidget *w)
@@ -467,7 +465,18 @@ Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w)
if (hiview){
OSWindowRef window = qt_mac_window_for(hiview);
if (!window && qt_isGenuineQWidget(hiview)) {
- w->window()->d_func()->createWindow_sys();
+ QWidget *myWindow = w->window();
+ // This is a workaround for NSToolbar. When a widget is hidden
+ // by clicking the toolbar button, Cocoa reparents the widgets
+ // to another window (but Qt doesn't know about it).
+ // When we start showing them, it reparents back,
+ // but at this point it's window is nil, but the window it's being brought
+ // into (the Qt one) is for sure created.
+ // This stops the hierarchy moving under our feet.
+ if (myWindow != w && qt_mac_window_for(qt_mac_nativeview_for(myWindow)))
+ return qt_mac_window_for(qt_mac_nativeview_for(myWindow));
+
+ myWindow->d_func()->createWindow_sys();
// Reget the hiview since the "create window could potentially move the view (I guess).
hiview = qt_mac_nativeview_for(w);
window = qt_mac_window_for(hiview);
@@ -2174,11 +2183,13 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin
if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) {
[windowRef setHidesOnDeactivate:YES];
[windowRef setHasShadow:YES];
+ } else {
+ [windowRef setHidesOnDeactivate:NO];
}
+
Q_UNUSED(parentWidget);
Q_UNUSED(dialog);
- // May need to do something the equivalent to ReshapeCustomWindow from Carbon here stuff, currently seems OK.
data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
OSViewRef nsview = (OSViewRef)data.winid;
OSViewRef window_contentview = qt_mac_get_contentview_for(windowRef);
@@ -2515,6 +2526,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
}
updateIsOpaque();
+ if (q->hasFocus())
+ setFocus_sys();
if (!topLevel && initializeWindow)
setWSGeometry();
@@ -2845,12 +2858,26 @@ void QWidgetPrivate::updateSystemBackground()
void QWidgetPrivate::setCursor_sys(const QCursor &)
{
+#ifndef QT_MAC_USE_COCOA
qt_mac_update_cursor();
+#else
+ Q_Q(QWidget);
+ if (q->testAttribute(Qt::WA_WState_Created)) {
+ [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
+ }
+#endif
}
void QWidgetPrivate::unsetCursor_sys()
{
+#ifndef QT_MAC_USE_COCOA
qt_mac_update_cursor();
+#else
+ Q_Q(QWidget);
+ if (q->testAttribute(Qt::WA_WState_Created)) {
+ [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
+ }
+#endif
}
void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
@@ -3275,6 +3302,20 @@ void QWidgetPrivate::show_sys()
qt_event_request_window_change(q);
}
+
+QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
+{
+#ifndef QT_MAC_USE_COCOA
+ CGPoint nativePoint = CGPointMake(pt.x(), pt.y());
+ HIViewConvertPoint(&nativePoint, qt_mac_nativeview_for(child->parentWidget()),
+ qt_mac_nativeview_for(child));
+#else
+ NSPoint nativePoint = [qt_mac_nativeview_for(child) convertPoint:NSMakePoint(pt.x(), pt.y()) fromView:qt_mac_nativeview_for(child->parentWidget())];
+#endif
+ return QPoint(nativePoint.x, nativePoint.y);
+}
+
+
void QWidgetPrivate::hide_sys()
{
Q_Q(QWidget);
@@ -3556,7 +3597,10 @@ void QWidgetPrivate::raise_sys()
#if QT_MAC_USE_COCOA
QMacCocoaAutoReleasePool pool;
if (isRealWindow()) {
- [qt_mac_window_for(q) orderFront:qt_mac_window_for(q)];
+ // Calling orderFront shows the window on Cocoa too.
+ if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ [qt_mac_window_for(q) orderFront:qt_mac_window_for(q)];
+ }
if (qt_mac_raise_process) { //we get to be the active process now
ProcessSerialNumber psn;
GetCurrentProcess(&psn);
@@ -4579,11 +4623,11 @@ void QWidgetPrivate::setModal_sys()
OSWindowRef windowRef = qt_mac_window_for(q);
#ifdef QT_MAC_USE_COCOA
- bool windowIsSheet = [windowRef styleMask] & NSDocModalWindowMask;
+ bool alreadySheet = [windowRef styleMask] & NSDocModalWindowMask;
- if (q->windowModality() == Qt::WindowModal){
+ if (windowParent && q->windowModality() == Qt::WindowModal){
// Window should be window-modal, which implies a sheet.
- if (!windowIsSheet)
+ if (!alreadySheet)
recreateMacWindow();
if ([windowRef isKindOfClass:[NSPanel class]]){
// If the primary window of the sheet parent is a child of a modal dialog,
@@ -4597,7 +4641,7 @@ void QWidgetPrivate::setModal_sys()
}
} else {
// Window shold not be window-modal, and as such, not a sheet.
- if (windowIsSheet){
+ if (alreadySheet){
// NB: the following call will call setModal_sys recursivly:
recreateMacWindow();
windowRef = qt_mac_window_for(q);
@@ -4612,6 +4656,7 @@ void QWidgetPrivate::setModal_sys()
if ([windowRef isKindOfClass:[NSPanel class]])
[static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
} else {
+ // INVARIANT: q should not be modal.
NSInteger winLevel = -1;
if (q->windowType() == Qt::Popup) {
winLevel = NSPopUpMenuWindowLevel;
@@ -4622,9 +4667,10 @@ void QWidgetPrivate::setModal_sys()
}
} else if (q->windowType() == Qt::Tool) {
winLevel = NSFloatingWindowLevel;
+ } else if (q->windowType() == Qt::Dialog) {
+ winLevel = NSModalPanelWindowLevel;
}
-
// StayOnTop window should appear above Tool windows.
if (data.window_flags & Qt::WindowStaysOnTopHint)
winLevel = NSPopUpMenuWindowLevel;
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index f254c4a..9e93f66 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -354,8 +354,6 @@ public:
void setWindowIcon_sys(bool forceReset = false);
void setWindowOpacity_sys(qreal opacity);
- void focusInputContext();
-
void adjustQuitOnCloseAttribute();
#if defined(Q_WS_X11)
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 228ef7c..ffbb341 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -1037,6 +1037,8 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
#else
UINT style = WS_POPUP;
#endif
+ if (d->topData()->savedFlags & WS_SYSMENU)
+ style |= WS_SYSMENU;
if (isVisible())
style |= WS_VISIBLE;
SetWindowLongA(internalWinId(), GWL_STYLE, style);
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index a12b50c..76734d4 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -898,7 +898,7 @@ void QWidgetPrivate::x11UpdateIsOpaque()
bool visible = q->isVisible();
if (visible)
q->hide();
- q->setParent(q->parentWidget(), q->windowFlags() & ~Qt::WindowType_Mask);
+ q->setParent(q->parentWidget(), q->windowFlags());
q->move(pos);
if (visible)
q->show();
@@ -1516,7 +1516,6 @@ void QWidget::activateWindow()
X11->userTime = X11->time;
qt_net_update_user_time(tlw, X11->userTime);
XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
- d->focusInputContext();
}
}
@@ -1751,8 +1750,8 @@ void QWidgetPrivate::show_sys()
mwmhints.functions &= ~MWM_FUNC_RESIZE;
}
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
if (mwmhints.decorations == MWM_DECOR_ALL) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
mwmhints.decorations = (MWM_DECOR_BORDER
| MWM_DECOR_TITLE
| MWM_DECOR_MENU);
@@ -1761,10 +1760,12 @@ void QWidgetPrivate::show_sys()
}
if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
mwmhints.decorations |= MWM_DECOR_MINIMIZE;
mwmhints.functions |= MWM_FUNC_MINIMIZE;
}
if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
mwmhints.functions |= MWM_FUNC_MAXIMIZE;
}
diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp
index e49c4d6..6329135 100644
--- a/src/gui/kernel/qx11embed_x11.cpp
+++ b/src/gui/kernel/qx11embed_x11.cpp
@@ -481,7 +481,7 @@ QX11EmbedWidget::QX11EmbedWidget(QWidget *parent)
| ExposureMask | StructureNotifyMask
| SubstructureNotifyMask | PropertyChangeMask);
- unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};
+ long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
XChangeProperty(x11Info().display(), internalWinId(), ATOM(_XEMBED_INFO),
ATOM(_XEMBED_INFO), 32, PropModeReplace,
(unsigned char*) data, 2);
@@ -1571,7 +1571,7 @@ void QX11EmbedContainer::showEvent(QShowEvent *)
{
Q_D(QX11EmbedContainer);
if (d->client) {
- unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};
+ long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
PropModeReplace, (unsigned char *) data, 2);
}
@@ -1587,8 +1587,7 @@ void QX11EmbedContainer::hideEvent(QHideEvent *)
{
Q_D(QX11EmbedContainer);
if (d->client) {
- unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};
-
+ long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
PropModeReplace, (unsigned char *) data, 2);
}
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index cf73eb7..6589439 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -153,12 +153,13 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha {
template <typename SRC, typename T>
void qt_scale_image_16bit(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
+ const QRectF &target,
const QRectF &srcRect,
const QRect &clip,
T blender)
{
-
+ const QRectF targetRect = target.translated(aliasedCoordinateDelta,
+ aliasedCoordinateDelta);
qreal sx = targetRect.width() / (qreal) srcRect.width();
qreal sy = targetRect.height() / (qreal) srcRect.height();
@@ -177,10 +178,10 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
int cy1 = clip.top();
int cy2 = clip.y() + clip.height();
- int tx1 = qFloor(targetRect.left() + aliasedCoordinateDelta);
- int tx2 = qFloor(targetRect.right() + aliasedCoordinateDelta);
- int ty1 = qFloor(targetRect.top() + aliasedCoordinateDelta);
- int ty2 = qFloor(targetRect.bottom() + aliasedCoordinateDelta);
+ int tx1 = qRound(targetRect.left());
+ int tx2 = qRound(targetRect.right());
+ int ty1 = qRound(targetRect.top());
+ int ty2 = qRound(targetRect.bottom());
if (tx2 < tx1)
qSwap(tx2, tx1);
@@ -534,6 +535,8 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
s += BYTE_MUL_RGB16(*dst, 255 - alpha);
*dst = s;
}
+ ++dst;
+ ++src;
}
dst += dstExtraStride;
src += srcExtraStride;
@@ -702,11 +705,14 @@ struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha {
template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
+ const QRectF &target,
const QRectF &srcRect,
const QRect &clip,
T blender)
{
+ const QRectF targetRect = target.translated(aliasedCoordinateDelta,
+ aliasedCoordinateDelta);
+
qreal sx = targetRect.width() / (qreal) srcRect.width();
qreal sy = targetRect.height() / (qreal) srcRect.height();
@@ -724,10 +730,10 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int cy1 = clip.top();
int cy2 = clip.y() + clip.height();
- int tx1 = qFloor(targetRect.left() + aliasedCoordinateDelta);
- int tx2 = qFloor(targetRect.right() + aliasedCoordinateDelta);
- int ty1 = qFloor(targetRect.top() + aliasedCoordinateDelta);
- int ty2 = qFloor(targetRect.bottom() + aliasedCoordinateDelta);
+ int tx1 = qRound(targetRect.left());
+ int tx2 = qRound(targetRect.right());
+ int ty1 = qRound(targetRect.top());
+ int ty2 = qRound(targetRect.bottom());
if (tx2 < tx1)
qSwap(tx2, tx1);
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index d44e2a6..5d7d4ab 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -526,7 +526,6 @@ void QColor::setNamedColor(const QString &name)
if (qt_get_hex_rgb(name.constData(), name.length(), &rgb)) {
setRgb(rgb);
} else {
- qWarning("QColor::setNamedColor: Could not parse color '%s'", name.toLatin1().constData());
invalidate();
}
return;
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 40ff379..4439d52 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -633,6 +633,8 @@ QPolygonF QMatrix::map(const QPolygonF &a) const
\sa QMatrix::map()
*/
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
/*!
\fn QRegion QMatrix::map(const QRegion &region) const
\overload
@@ -653,7 +655,6 @@ QRegion QMatrix::map(const QRegion &r) const
return copy;
}
- extern QPainterPath qt_regionToPath(const QRegion &region);
QPainterPath p = map(qt_regionToPath(r));
return p.toFillPolygon().toPolygon();
}
diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp
index e38f6a4..74cbebe 100644
--- a/src/gui/painting/qpaintengine_alpha.cpp
+++ b/src/gui/painting/qpaintengine_alpha.cpp
@@ -80,6 +80,7 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
d->m_advancedPen = false;
d->m_advancedBrush = false;
d->m_complexTransform = false;
+ d->m_emulateProjectiveTransforms = false;
// clear alpha region
d->m_alphargn = QRegion();
@@ -116,6 +117,9 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
if (flags & QPaintEngine::DirtyTransform) {
d->m_transform = state.transform();
d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
+ d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
+ && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
+ && (d->m_transform.type() >= QTransform::TxProject);
}
if (flags & QPaintEngine::DirtyPen) {
d->m_pen = state.pen();
@@ -163,7 +167,9 @@ void QAlphaPaintEngine::drawPath(const QPainterPath &path)
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
if (d->m_picengine)
@@ -187,7 +193,9 @@ void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
diff --git a/src/gui/painting/qpaintengine_alpha_p.h b/src/gui/painting/qpaintengine_alpha_p.h
index f510c73..f7d7a34 100644
--- a/src/gui/painting/qpaintengine_alpha_p.h
+++ b/src/gui/painting/qpaintengine_alpha_p.h
@@ -113,6 +113,7 @@ public:
bool m_advancedPen;
bool m_advancedBrush;
bool m_complexTransform;
+ bool m_emulateProjectiveTransforms;
bool m_continueCall;
QTransform m_transform;
diff --git a/src/gui/painting/qpaintengine_d3d.cpp b/src/gui/painting/qpaintengine_d3d.cpp
index 26708b0..bb81623 100644
--- a/src/gui/painting/qpaintengine_d3d.cpp
+++ b/src/gui/painting/qpaintengine_d3d.cpp
@@ -2866,9 +2866,10 @@ void QDirect3DPaintEnginePrivate::updateClipPath(const QPainterPath &path, Qt::C
m_draw_helper->setClipPath(m_clip_path, aaitem); */
}
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
void QDirect3DPaintEnginePrivate::updateClipRegion(const QRegion &clipregion, Qt::ClipOperation op)
{
- extern QPainterPath qt_regionToPath(const QRegion &region);
if (m_draw_helper->needsFlushing())
flushBatch();
if (m_has_complex_clipping) {
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 495e6c4..addd63d 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -104,6 +104,8 @@
QT_BEGIN_NAMESPACE
+extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+
#define qreal_to_fixed_26_6(f) (int(f * 64))
#define qt_swap_int(x, y) { int tmp = (x); (x) = (y); (y) = tmp; }
#define qt_swap_qreal(x, y) { qreal tmp = (x); (x) = (y); (y) = tmp; }
@@ -607,7 +609,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
break;
}
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
ensureOutlineMapper();
@@ -1528,7 +1529,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->initializeRasterizer(&s->brushData);
for (int i = 0; i < rectCount; ++i) {
const QRectF &rect = rects[i].normalized();
- if (rects[i].isEmpty())
+ if (rect.isEmpty())
continue;
const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);
@@ -1701,10 +1702,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
static inline QRect toNormalizedFillRect(const QRectF &rect)
{
- const int x1 = qFloor(rect.x() + aliasedCoordinateDelta);
- const int y1 = qFloor(rect.y() + aliasedCoordinateDelta);
- const int x2 = qFloor(rect.right() + aliasedCoordinateDelta);
- const int y2 = qFloor(rect.bottom() + aliasedCoordinateDelta);
+ const int x1 = qRound(rect.x() + aliasedCoordinateDelta);
+ const int y1 = qRound(rect.y() + aliasedCoordinateDelta);
+ const int x2 = qRound(rect.right() + aliasedCoordinateDelta);
+ const int y2 = qRound(rect.bottom() + aliasedCoordinateDelta);
return QRect(x1, y1, x2 - x1, y2 - y1).normalized();
}
@@ -1906,7 +1907,6 @@ void QRasterPaintEngine::drawPath(const QPainterPath &path)
} else {
Q_ASSERT(s->stroker);
d->outlineMapper->beginOutline(Qt::WindingFill);
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
qreal txscale = 1;
if (s->pen.isCosmetic() || (qt_scaleForTransform(s->matrix, &txscale) && txscale != 1)) {
const qreal strokeWidth = d->basicStroker.strokeWidth();
@@ -2355,11 +2355,6 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCo
}
}
-#define IMAGE_FROM_PIXMAP(pixmap) \
- pixmap.data->classId() == QPixmapData::RasterClass \
- ? ((QRasterPixmapData *) pixmap.data)->image \
- : pixmap.toImage()
-
/*!
\internal
*/
@@ -2368,16 +2363,33 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
#ifdef QT_DEBUG_DRAW
qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- if (pixmap.depth() == 1) {
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
- if (s->matrix.type() <= QTransform::TxTranslate) {
- drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
} else {
- drawImage(pos, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color()));
+ QRasterPaintEngine::drawImage(pos, image);
}
} else {
- QRasterPaintEngine::drawImage(pos, IMAGE_FROM_PIXMAP(pixmap));
+ const QImage image = pixmap.toImage();
+ if (pixmap.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
+ } else {
+ QRasterPaintEngine::drawImage(pos, image);
+ }
}
}
@@ -2390,22 +2402,40 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons
qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- if (pixmap.depth() == 1) {
- if (s->matrix.type() <= QTransform::TxTranslate
- && r.size() == sr.size()
- && r.size() == pixmap.size()) {
- ensurePen();
- drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
- return;
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
} else {
- drawImage(r, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap),
- s->pen.color()), sr);
+ drawImage(r, image, sr);
}
} else {
- drawImage(r, IMAGE_FROM_PIXMAP(pixmap), sr);
+ const QImage image = pixmap.toImage();
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
+ } else {
+ drawImage(r, image, sr);
+ }
}
}
@@ -2614,10 +2644,15 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
QRasterPaintEngineState *s = state();
QImage image;
- if (pixmap.depth() == 1)
- image = d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color());
- else
- image = IMAGE_FROM_PIXMAP(pixmap);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ image = ((QRasterPixmapData *) pixmap.data)->image;
+ } else {
+ image = pixmap.toImage();
+ }
+
+ if (image.depth() == 1)
+ image = d->rasterBuffer->colorizeBitmap(image, s->pen.color());
if (s->matrix.type() > QTransform::TxTranslate) {
QTransform copy = s->matrix;
@@ -3650,14 +3685,13 @@ void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
}
#endif // Q_WS_QWS
-void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpanData *fg)
+void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg)
{
Q_ASSERT(fg);
if (!fg->blend)
return;
Q_D(QRasterPaintEngine);
- const QImage image = IMAGE_FROM_PIXMAP(pm);
Q_ASSERT(image.depth() == 1);
const int spanCount = 256;
@@ -3665,8 +3699,8 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpan
int n = 0;
// Boundaries
- int w = pm.width();
- int h = pm.height();
+ int w = image.width();
+ int h = image.height();
int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());
int ymin = qMax(qRound(pos.y()), 0);
int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 0f8060a..26a2b3f 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -256,7 +256,7 @@ private:
void init();
void fillRect(const QRectF &rect, QSpanData *data);
- void drawBitmap(const QPointF &pos, const QPixmap &image, QSpanData *fill);
+ void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index e9f1bb3..39ce59f 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -62,6 +62,7 @@
#include <private/qpaintengine_x11_p.h>
#include <private/qfontengine_x11_p.h>
#include <private/qwidget_p.h>
+#include <private/qpainterpath_p.h>
#include "qpen.h"
#include "qcolor.h"
@@ -1479,14 +1480,10 @@ void QX11PaintEngine::drawEllipse(const QRect &rect)
return;
}
d->setupAdaptedOrigin(rect.topLeft());
- if (d->has_brush) { // draw filled ellipse
- if (!d->has_pen) {
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
+ if (d->has_brush) { // draw filled ellipse
+ XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
+ if (!d->has_pen) // make smoother outline
XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
- return;
- } else{
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
- }
}
if (d->has_pen) // draw outline
XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
@@ -1760,9 +1757,14 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
QPainterPath stroke;
qreal width = d->cpen.widthF();
QPolygonF poly;
+ QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height());
// necessary to get aliased alphablended primitives to be drawn correctly
if (d->cpen.isCosmetic() || d->has_scaling_xform) {
- stroker.setWidth(width == 0 ? 1 : width * d->xform_scale);
+ if (d->cpen.isCosmetic())
+ stroker.setWidth(width == 0 ? 1 : width);
+ else
+ stroker.setWidth(width * d->xform_scale);
+ stroker.d_ptr->stroker.setClipRect(deviceRect);
stroke = stroker.createStroke(path * d->matrix);
if (stroke.isEmpty())
return;
@@ -1770,6 +1772,7 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);
} else {
stroker.setWidth(width);
+ stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect));
stroke = stroker.createStroke(path);
if (stroke.isEmpty())
return;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 72dd189..8eaad60 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -258,6 +258,8 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
return new QPainterState(orig);
}
+extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
{
#ifdef QT_DEBUG_DRAW
@@ -326,7 +328,6 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
flags |= QVectorPath::CurvedShapeHint;
// ### Perspective Xforms are currently not supported...
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
qreal txscale = 1;
if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) {
// We include cosmetic pens in this case to avoid having to
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 1f61e2f..2fa6a56 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1293,7 +1293,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
destination.
Note that composition transformation operates pixelwise. For that
- reason, there is a difference between using the grahic primitive
+ reason, there is a difference between using the graphic primitive
itself and its bounding rectangle: The bounding rect contains
pixels with alpha == 0 (i.e the pixels surrounding the
primitive). These pixels will overwrite the other image's pixels,
@@ -1465,8 +1465,8 @@ bool QPainter::isActive() const
/*!
Initializes the painters pen, background and font to the same as
- the given \a widget. Call this function after begin() while the
- painter is active.
+ the given \a widget. This function is called automatically when the
+ painter is opened on a QWidget.
\sa begin(), {QPainter#Settings}{Settings}
*/
@@ -2371,6 +2371,11 @@ void QPainter::setClipping(bool enable)
Returns the currently set clip region. Note that the clip region
is given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipRegion(), clipPath(), setClipping()
*/
@@ -2480,10 +2485,17 @@ QRegion QPainter::clipRegion() const
return region;
}
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
/*!
Returns the currently clip as a path. Note that the clip path is
given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipPath(), clipRegion(), setClipping()
*/
QPainterPath QPainter::clipPath() const
@@ -2520,7 +2532,6 @@ QPainterPath QPainter::clipPath() const
return path * matrix;
} else {
// Fallback to clipRegion() for now, since we don't have isect/unite for paths
- extern QPainterPath qt_regionToPath(const QRegion &region);
return qt_regionToPath(clipRegion());
}
}
@@ -3084,6 +3095,9 @@ void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
return;
}
+ if (path.isEmpty())
+ return;
+
if (d->extended) {
const QGradient *g = qpen_brush(pen).gradient();
if (!g || g->coordinateMode() == QGradient::LogicalMode) {
@@ -3124,6 +3138,9 @@ void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
return;
}
+ if (path.isEmpty())
+ return;
+
if (d->extended) {
const QGradient *g = brush.gradient();
if (!g || g->coordinateMode() == QGradient::LogicalMode) {
@@ -5148,9 +5165,6 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
- if (!d->engine || pm.isNull())
- return;
-
#ifndef QT_NO_DEBUG
qt_painter_thread_test(d->device->devType(), "drawPixmap()");
#endif
@@ -5160,12 +5174,18 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
}
+ if (!d->engine)
+ return;
+
qreal x = p.x();
qreal y = p.y();
int w = pm.width();
int h = pm.height();
+ if (w <= 0)
+ return;
+
// Emulate opaque background for bitmaps
if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index bb07f81..e1f5eea 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1725,7 +1725,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
*/
bool QPainterPath::contains(const QPointF &pt) const
{
- if (isEmpty())
+ if (isEmpty() || !controlPointRect().contains(pt))
return false;
QPainterPathData *d = d_func();
@@ -2387,21 +2387,13 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,
\sa QPen, QBrush
*/
-class QPainterPathStrokerPrivate
+QPainterPathStrokerPrivate::QPainterPathStrokerPrivate()
+ : dashOffset(0)
{
-public:
- QPainterPathStrokerPrivate()
- : dashOffset(0)
- {
- stroker.setMoveToHook(qt_path_stroke_move_to);
- stroker.setLineToHook(qt_path_stroke_line_to);
- stroker.setCubicToHook(qt_path_stroke_cubic_to);
- }
-
- QStroker stroker;
- QVector<qfixed> dashPattern;
- qreal dashOffset;
-};
+ stroker.setMoveToHook(qt_path_stroke_move_to);
+ stroker.setLineToHook(qt_path_stroke_line_to);
+ stroker.setCubicToHook(qt_path_stroke_cubic_to);
+}
/*!
Creates a new stroker.
@@ -2445,6 +2437,7 @@ QPainterPath QPainterPathStroker::createStroke(const QPainterPath &path) const
QDashStroker dashStroker(&d->stroker);
dashStroker.setDashPattern(d->dashPattern);
dashStroker.setDashOffset(d->dashOffset);
+ dashStroker.setClipRect(d->stroker.clipRect());
dashStroker.strokePath(path, &stroke, QTransform());
}
stroke.setFillRule(Qt::WindingFill);
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 88fb19d..6cd2af8 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -277,6 +277,8 @@ public:
QPainterPath createStroke(const QPainterPath &path) const;
private:
+ friend class QX11PaintEngine;
+
QPainterPathStrokerPrivate *d_ptr;
};
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 93f9704..29c48df 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -61,9 +61,20 @@
#include <qdebug.h>
#include <private/qvectorpath_p.h>
+#include <private/qstroker_p.h>
QT_BEGIN_NAMESPACE
+class QPainterPathStrokerPrivate
+{
+public:
+ QPainterPathStrokerPrivate();
+
+ QStroker stroker;
+ QVector<qfixed> dashPattern;
+ qreal dashOffset;
+};
+
class QPolygonF;
class QVectorPathConverter;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 4a87f6a..55006f6 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1106,6 +1106,11 @@ void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
if (!d->hasPen || (d->clipEnabled && d->allClipped))
return;
+ if (d->stroker.matrix.type() >= QTransform::TxProject) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
*d->currentPage << "q\n";
if(!d->simplePen)
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
@@ -1226,6 +1231,8 @@ void QPdfBaseEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
setPen();
}
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
{
Q_D(QPdfBaseEngine);
@@ -1252,7 +1259,6 @@ void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
// if we have an alpha region, we have to subtract that from the
// any existing clip region since that region will be filled in
// later with images
- extern QPainterPath qt_regionToPath(const QRegion &region);
QPainterPath alphaClip = qt_regionToPath(alphaClipping());
if (!alphaClip.isEmpty()) {
if (!d->clipEnabled) {
diff --git a/src/gui/painting/qprintengine_mac.mm b/src/gui/painting/qprintengine_mac.mm
index 7a77e47..b1216b7 100644
--- a/src/gui/painting/qprintengine_mac.mm
+++ b/src/gui/painting/qprintengine_mac.mm
@@ -62,6 +62,10 @@ bool QMacPrintEngine::begin(QPaintDevice *dev)
{
Q_D(QMacPrintEngine);
+ Q_ASSERT(dev && dev->devType() == QInternal::Printer);
+ if (!static_cast<QPrinter *>(dev)->isValid())
+ return false;
+
if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
d->initialize();
@@ -121,24 +125,8 @@ bool QMacPrintEngine::end()
if(d->paintEngine->type() == QPaintEngine::CoreGraphics)
static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
d->paintEngine->end();
- if (d->state != QPrinter::Idle) {
-#ifndef QT_MAC_USE_COCOA
- if (d->shouldSuppressStatus()) {
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- } else {
- PMSessionEndPage(d->session);
- PMSessionEndDocument(d->session);
- }
- PMRelease(d->session);
-#else
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- [d->printInfo release];
-#endif
- d->printInfo = 0;
- d->session = 0;
- }
+ if (d->state != QPrinter::Idle)
+ d->releaseSession();
d->state = QPrinter::Idle;
return true;
}
@@ -509,6 +497,26 @@ void QMacPrintEnginePrivate::initialize()
}
}
+void QMacPrintEnginePrivate::releaseSession()
+{
+#ifndef QT_MAC_USE_COCOA
+ if (shouldSuppressStatus()) {
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ } else {
+ PMSessionEndPage(session);
+ PMSessionEndDocument(session);
+ }
+ PMRelease(session);
+#else
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ [printInfo release];
+#endif
+ printInfo = 0;
+ session = 0;
+}
+
bool QMacPrintEnginePrivate::newPage_helper()
{
Q_Q(QMacPrintEngine);
@@ -737,6 +745,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->setPaperSize(QPrinter::PaperSize(value.toInt()));
break;
case PPK_PrinterName: {
+ bool printerNameSet = false;
OSStatus status = noErr;
QCFType<CFArrayRef> printerList;
status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
@@ -747,12 +756,18 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
QString name = QCFString::toQString(PMPrinterGetName(printer));
if (name == value.toString()) {
status = PMSessionSetCurrentPMPrinter(d->session, printer);
+ printerNameSet = true;
break;
}
}
}
if (status != noErr)
qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
+ if (!printerNameSet) {
+ qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
+ d->releaseSession();
+ d->state = QPrinter::Idle;
+ }
break; }
case PPK_SuppressSystemPrintStatus:
d->suppressStatus = value.toBool();
@@ -876,17 +891,12 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = r;
break; }
case PPK_PrinterName: {
- CFIndex currIndex;
- PMPrinter unused;
- QCFType<CFArrayRef> printerList;
- OSStatus status = PMSessionCreatePrinterList(d->session, &printerList, &currIndex, &unused);
+ PMPrinter printer;
+ OSStatus status = PMSessionGetCurrentPrinter(d->session, &printer);
if (status != noErr)
- qWarning("QMacPrintEngine::printerName: Problem getting list of printers: %ld", long(status));
- if (currIndex != -1 && printerList && currIndex < CFArrayGetCount(printerList)) {
- const CFStringRef name = static_cast<CFStringRef>(CFArrayGetValueAtIndex(printerList, currIndex));
- if (name)
- ret = QCFString::toQString(name);
- }
+ qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
+ if (printer)
+ ret = QCFString::toQString(PMPrinterGetName(printer));
break; }
case PPK_Resolution: {
ret = d->resolution.hRes;
diff --git a/src/gui/painting/qprintengine_mac_p.h b/src/gui/painting/qprintengine_mac_p.h
index 5e18845..bc917e7 100644
--- a/src/gui/painting/qprintengine_mac_p.h
+++ b/src/gui/painting/qprintengine_mac_p.h
@@ -143,6 +143,7 @@ public:
hasCustomPaperSize(false), hasCustomPageMargins(false) {}
~QMacPrintEnginePrivate();
void initialize();
+ void releaseSession();
bool newPage_helper();
void setPaperSize(QPrinter::PaperSize ps);
QPrinter::PaperSize paperSize() const;
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index fdd44ba..c8674b7 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -58,12 +58,13 @@
QT_BEGIN_NAMESPACE
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
// #define QT_DEBUG_DRAW
static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc,
bool convertToText, const QTransform &xform, const QPointF &topLeft);
-
static const struct {
int winSizeName;
QPrinter::PaperSize qtSizeName;
@@ -368,7 +369,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem
QRgb brushColor = state->pen().brush().color().rgb();
bool fallBack = state->pen().brush().style() != Qt::SolidPattern
|| qAlpha(brushColor) != 0xff
- || QT_WA_INLINE(false, d->txop >= QTransform::TxScale)
+ || QT_WA_INLINE(d->txop >= QTransform::TxProject, d->txop >= QTransform::TxScale)
|| ti.fontEngine->type() != QFontEngine::Win;
@@ -586,7 +587,6 @@ void QWin32PrintEngine::updateState(const QPaintEngineState &state)
if (state.state() & DirtyClipRegion) {
QRegion clipRegion = state.clipRegion();
- extern QPainterPath qt_regionToPath(const QRegion &region);
QPainterPath clipPath = qt_regionToPath(clipRegion);
updateClipPath(clipPath, state.clipOperation());
}
@@ -621,7 +621,6 @@ void QWin32PrintEngine::updateClipPath(const QPainterPath &clipPath, Qt::ClipOpe
}
}
- extern QPainterPath qt_regionToPath(const QRegion &region);
QPainterPath aclip = qt_regionToPath(alphaClipping());
if (!aclip.isEmpty()) {
QTransform tx(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y);
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index 413f4a1..4f3e71c 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -284,6 +284,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
to send PostScript or PDF output to the printer. As an alternative,
the printProgram() function can be used to specify the command or utility
to use instead of the system default.
+
+ Note that setting parameters like paper size and resolution on an
+ invalid printer is undefined. You can use QPrinter::isValid() to
+ verify this before changing any parameters.
QPrinter supports a number of parameters, most of which can be
changed by the end user through a \l{QPrintDialog}{print dialog}. In
@@ -849,7 +853,7 @@ void QPrinter::setPrinterName(const QString &name)
Returns true if the printer currently selected is a valid printer
in the system, or a pure PDF/PostScript printer; otherwise returns false.
- To detect other failures check the output of QPainter::begin() or QPainter::nextPage().
+ To detect other failures check the output of QPainter::begin() or QPrinter::newPage().
\snippet doc/src/snippets/printing-qprinter/errors.cpp 0
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index f728f9d..c88af7c 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qregion.h"
+#include "qpainterpath.h"
#include "qpolygon.h"
#include "qbuffer.h"
#include "qdatastream.h"
@@ -49,7 +50,6 @@
#include <qdebug.h>
#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
-#include "qpainterpath.h"
#include "qimage.h"
#include "qbitmap.h"
#include <stdlib.h>
@@ -65,9 +65,17 @@ QT_BEGIN_NAMESPACE
\ingroup shared
QRegion is used with QPainter::setClipRegion() to limit the paint
- area to what needs to be painted. There is also a
- QWidget::repaint() function that takes a QRegion parameter.
- QRegion is the best tool for reducing flicker.
+ area to what needs to be painted. There is also a QWidget::repaint()
+ function that takes a QRegion parameter. QRegion is the best tool for
+ minimizing the amount of screen area to be updated by a repaint.
+
+ This class is not suitable for constructing shapes for rendering, especially
+ as outlines. Use QPainterPath to create paths and shapes for use with
+ QPainter.
+
+ QRegion is an \l{implicitly shared} class.
+
+ \section1 Creating and Using Regions
A region can be created from a rectangle, an ellipse, a polygon or
a bitmap. Complex regions may be created by combining simple
@@ -84,8 +92,6 @@ QT_BEGIN_NAMESPACE
Example of using complex regions:
\snippet doc/src/snippets/code/src_gui_painting_qregion.cpp 0
- QRegion is an \l{implicitly shared} class.
-
\warning Due to window system limitations, the whole coordinate space for a
region is limited to the points between -32767 and 32767 on Windows
95/98/ME. You can circumvent this limitation by using a QPainterPath.
@@ -93,7 +99,7 @@ QT_BEGIN_NAMESPACE
\section1 Additional License Information
On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on
- code obtained under the following license:
+ code obtained under the following licenses:
\legalese
Copyright (c) 1987 X Consortium
@@ -120,9 +126,7 @@ QT_BEGIN_NAMESPACE
in this Software without prior written authorization from the X Consortium.
\endlegalese
- \raw HTML
- <hr />
- \endraw
+ \br
\legalese
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index c2e2a80..39e429d 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -168,10 +168,10 @@ QT_BEGIN_NAMESPACE
\image qtransform-representation.png
- A QTransform object contains a 3 x 3 matrix. The \c dx and \c dy
- elements specify horizontal and vertical translation. The \c m11
- and \c m22 elements specify horizontal and vertical scaling. The
- \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
+ A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and
+ \c m32 (\c dy) elements specify horizontal and vertical translation.
+ The \c m11 and \c m22 elements specify horizontal and vertical scaling.
+ The \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
And finally, the \c m13 and \c m23 elements specify horizontal and vertical
projection, with \c m33 as an additional projection factor.
@@ -246,8 +246,10 @@ QTransform::QTransform()
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h13,
- \a h21, \a h22, \a h23, \a h31, \a h32, \a h33.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m13,
+ \a m21, \a m22, \a m23, \a m31, \a m32, \a m33.
\sa setMatrix()
*/
@@ -263,8 +265,9 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13,
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h21, \a
- h22, \a dx and \a dy.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy.
\sa setMatrix()
*/
@@ -396,6 +399,9 @@ QTransform QTransform::inverted(bool *invertible) const
*/
QTransform & QTransform::translate(qreal dx, qreal dy)
{
+ if (dx == 0 && dy == 0)
+ return *this;
+
switch(type()) {
case TxNone:
affine._dx = dx;
@@ -432,7 +438,10 @@ QTransform & QTransform::translate(qreal dx, qreal dy)
QTransform QTransform::fromTranslate(qreal dx, qreal dy)
{
QTransform transform(1, 0, 0, 1, dx, dy);
- transform.m_dirty = TxTranslate;
+ if (dx == 0 && dy == 0)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxTranslate;
return transform;
}
@@ -444,6 +453,9 @@ QTransform QTransform::fromTranslate(qreal dx, qreal dy)
*/
QTransform & QTransform::scale(qreal sx, qreal sy)
{
+ if (sx == 1 && sy == 1)
+ return *this;
+
switch(type()) {
case TxNone:
case TxTranslate:
@@ -478,7 +490,10 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
QTransform QTransform::fromScale(qreal sx, qreal sy)
{
QTransform transform(sx, 0, 0, sy, 0, 0);
- transform.m_dirty = TxScale;
+ if (sx == 1 && sy == 1)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxScale;
return transform;
}
@@ -541,6 +556,9 @@ const qreal inv_dist_to_plane = 1. / 1024.;
*/
QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
{
+ if (a == 0)
+ return *this;
+
qreal sina = 0;
qreal cosa = 0;
if (a == 90. || a == -270.)
@@ -712,7 +730,15 @@ bool QTransform::operator!=(const QTransform &o) const
*/
QTransform & QTransform::operator*=(const QTransform &o)
{
- TransformationType t = qMax(type(), o.type());
+ const TransformationType otherType = o.type();
+ if (otherType == TxNone)
+ return *this;
+
+ const TransformationType thisType = type();
+ if (thisType == TxNone)
+ return operator=(o);
+
+ TransformationType t = qMax(thisType, otherType);
switch(t) {
case TxNone:
break;
@@ -1219,7 +1245,8 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol
*/
QPolygonF QTransform::map(const QPolygonF &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, a);
int size = a.size();
@@ -1228,7 +1255,6 @@ QPolygonF QTransform::map(const QPolygonF &a) const
const QPointF *da = a.constData();
QPointF *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
MAP(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
}
@@ -1246,7 +1272,8 @@ QPolygonF QTransform::map(const QPolygonF &a) const
*/
QPolygon QTransform::map(const QPolygon &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, QPolygonF(a)).toPolygon();
int size = a.size();
@@ -1255,7 +1282,6 @@ QPolygon QTransform::map(const QPolygon &a) const
const QPoint *da = a.constData();
QPoint *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
qreal nx = 0, ny = 0;
MAP(da[i].xp, da[i].yp, nx, ny);
@@ -1274,6 +1300,8 @@ QPolygon QTransform::map(const QPolygon &a) const
\sa QTransform::map()
*/
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
/*!
\fn QRegion QTransform::map(const QRegion &region) const
\overload
@@ -1295,7 +1323,6 @@ QRegion QTransform::map(const QRegion &r) const
return copy;
}
- extern QPainterPath qt_regionToPath(const QRegion &region);
QPainterPath p = map(qt_regionToPath(r));
return p.toFillPolygon(QTransform()).toPolygon();
}
@@ -1688,13 +1715,12 @@ QRect QTransform::mapRect(const QRect &rect) const
return QRect(x, y, w, h);
} else if (t < TxProject) {
// see mapToPolygon for explanations of the algorithm.
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.left(), rect.top(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.left(), rect.top(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.right() + 1, rect.top(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -1755,13 +1781,12 @@ QRectF QTransform::mapRect(const QRectF &rect) const
}
return QRectF(x, y, w, h);
} else if (t < TxProject) {
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.x(), rect.y(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.x(), rect.y(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.x() + rect.width(), rect.y(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -2057,10 +2082,11 @@ QTransform::operator QVariant() const
Q_GUI_EXPORT
bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
- if (transform.type() <= QTransform::TxTranslate) {
+ const QTransform::TransformationType type = transform.type();
+ if (type <= QTransform::TxTranslate) {
*scale = 1;
return true;
- } else if (transform.type() == QTransform::TxScale) {
+ } else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
*scale = qMax(xScale, yScale);
@@ -2072,7 +2098,7 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
*scale = qSqrt(qMax(xScale, yScale));
- return transform.type() == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
+ return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index de7ebcd..c76409b 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -257,6 +257,8 @@ inline qreal QTransform::dy() const
inline QTransform &QTransform::operator*=(qreal num)
{
+ if (num == 1.)
+ return *this;
affine._m11 *= num;
affine._m12 *= num;
m_13 *= num;
@@ -271,11 +273,15 @@ inline QTransform &QTransform::operator*=(qreal num)
}
inline QTransform &QTransform::operator/=(qreal div)
{
+ if (div == 0)
+ return *this;
div = 1/div;
return operator*=(div);
}
inline QTransform &QTransform::operator+=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 += num;
affine._m12 += num;
m_13 += num;
@@ -290,6 +296,8 @@ inline QTransform &QTransform::operator+=(qreal num)
}
inline QTransform &QTransform::operator-=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 -= num;
affine._m12 -= num;
m_13 -= num;
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
index bcb0380..d941a24 100644
--- a/src/gui/painting/qwindowsurface.cpp
+++ b/src/gui/painting/qwindowsurface.cpp
@@ -310,10 +310,13 @@ void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
int lineskip = img.bytesPerLine();
int depth = img.depth() >> 3;
-
- const QRect r = rect & QRect(0, 0, img.width(), img.height());
+ const QRect imageRect(0, 0, img.width(), img.height());
+ const QRect r = rect & imageRect & imageRect.translated(-offset);
const QPoint p = rect.topLeft() + offset;
+ if (r.isEmpty())
+ return;
+
const uchar *src;
uchar *dest;
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index 947f9a2..acb8437 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -75,6 +75,7 @@
QT_BEGIN_NAMESPACE
static bool displayDepth = -1;
+Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
typedef QHash<QString, GtkWidget*> WidgetMap;
Q_GLOBAL_STATIC(WidgetMap, gtkWidgetMap)
@@ -486,11 +487,11 @@ static void init_gtk_menu()
}
// Updates window/windowtext palette based on the indicated gtk widget
-static void ensureWidgetPalette(QWidget* widget, const QString &gtkWidgetName)
+static QPalette gtkWidgetPalette(const QString &gtkWidgetName)
{
GtkWidget *gtkWidget = QGtk::gtkWidget(gtkWidgetName);
Q_ASSERT(gtkWidget);
- QPalette pal = widget->palette();
+ QPalette pal = QApplication::palette();
GdkColor gdkBg = gtkWidget->style->bg[GTK_STATE_NORMAL];
GdkColor gdkText = gtkWidget->style->fg[GTK_STATE_NORMAL];
GdkColor gdkDisabledText = gtkWidget->style->fg[GTK_STATE_INSENSITIVE];
@@ -503,8 +504,7 @@ static void ensureWidgetPalette(QWidget* widget, const QString &gtkWidgetName)
pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
- widget->setPalette(pal);
- widget->setAttribute(Qt::WA_SetPalette, false);
+ return pal;
}
bool QGtk::isKDE4Session()
@@ -515,44 +515,47 @@ bool QGtk::isKDE4Session()
return (version == 4);
}
-// Maps a Gtk widget palettes to a Qt widget
-void QGtk::applyGtkSystemPalette(QWidget *widget)
+void QGtk::applyCustomPaletteHash()
{
- // Do not apply if the widget has a custom palette;
- if (widget->testAttribute(Qt::WA_SetPalette))
- return;
+ QPalette menuPal = gtkWidgetPalette(QLS("GtkMenu"));
+ GdkColor gdkBg = QGtk::gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ menuPal.setBrush(QPalette::Base, bgColor);
+ menuPal.setBrush(QPalette::Window, bgColor);
+ qApp->setPalette(menuPal, "QMenu");
- QPalette pal;
- if (QStatusBar *statusbar = qobject_cast<QStatusBar*> (widget))
- ensureWidgetPalette(statusbar, QLS("GtkStatusbar"));
- else if (QMenuBar *menubar = qobject_cast<QMenuBar*> (widget))
- ensureWidgetPalette(menubar, QLS("GtkMenuBar"));
- else if (QToolBar *toolbar = qobject_cast<QToolBar*> (widget))
- ensureWidgetPalette(toolbar, QLS("GtkToolbar"));
- else if (QMenu *menubar = qobject_cast<QMenu*> (widget)) {
- // This really applies to the combo box rendering since
- // QComboBox copies the palette from a QMenu
- QPalette pal = widget->palette();
- GdkColor gdkBg = QGtk::gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- pal.setBrush(QPalette::Base, bgColor);
- menubar->setPalette(pal);
- }
- widget->setAttribute(Qt::WA_SetPalette, false);
+ QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar"));
+ qApp->setPalette(toolbarPal, "QToolBar");
+
+ QPalette menuBarPal = gtkWidgetPalette(QLS("GtkMenuBar"));
+ qApp->setPalette(menuBarPal, "QMenuBar");
}
static void gtkStyleSetCallback(GtkWidget*, GtkStyle*, void*)
{
+ // We have to let this function return and complete the event
+ // loop to ensure that all gtk widgets have been styled before
+ // updating
+ QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection);
+}
+
+void QGtkStyleUpdateScheduler::updateTheme()
+{
static QString oldTheme(QLS("qt_not_set"));
QPixmapCache::clear();
- qApp->setFont(QGtk::getThemeFont());
- QGtk::initGtkWidgets();
if (oldTheme != getThemeName()) {
oldTheme = getThemeName();
- QApplicationPrivate::setSystemPalette(qApp->style()->standardPalette());
+ qApp->setFont(QGtk::getThemeFont());
+ QPalette newPalette = qApp->style()->standardPalette();
+ QApplicationPrivate::setSystemPalette(newPalette);
+ QApplication::setPalette(newPalette);
+ QGtk::initGtkWidgets();
+ QGtk::applyCustomPaletteHash();
QList<QWidget*> widgets = QApplication::allWidgets();
+ // Notify all widgets that size metrics might have changed
foreach (QWidget *widget, widgets) {
- QGtk::applyGtkSystemPalette(widget);
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &e);
}
}
}
@@ -629,17 +632,26 @@ GtkStyle* QGtk::gtkStyle(const QString &path)
return gtkWidgetMap()->value(path)->style;
return 0;
}
+
+#ifdef Q_OS_LINUX
QT_END_NAMESPACE
int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
QT_BEGIN_NAMESPACE
+#endif
+
void QGtk::initGtkWidgets()
{
// From gtkmain.c
+
uid_t ruid, rgid, euid, egid, suid, sgid;
- if (getresuid (&ruid, &euid, &suid) != 0 || getresgid (&rgid, &egid, &sgid) != 0) {
+
+#ifdef Q_OS_LINUX
+ if (getresuid (&ruid, &euid, &suid) != 0 || getresgid (&rgid, &egid, &sgid) != 0)
+#endif
+ {
suid = ruid = getuid ();
sgid = rgid = getgid ();
euid = geteuid ();
@@ -652,7 +664,7 @@ void QGtk::initGtkWidgets()
"See http://www.gtk.org/setuid.html for more information.\n");
return;
}
-
+
init_gtk_window();
if (QGtk::gtk_init) {
diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/gtksymbols_p.h
index 0cea542..74c5dc3 100644
--- a/src/gui/styles/gtksymbols_p.h
+++ b/src/gui/styles/gtksymbols_p.h
@@ -204,7 +204,7 @@ public:
static void cleanup_gtk_widgets();
static void initGtkWidgets();
static bool isKDE4Session();
- static void applyGtkSystemPalette(QWidget* widget);
+ static void applyCustomPaletteHash();
static QFont getThemeFont();
static bool isThemeAvailable() { return gtkStyle() != 0; }
@@ -329,6 +329,15 @@ public:
static Ptr_gconf_client_get_string gconf_client_get_string;
};
+// Helper to ensure that we have polished all our gtk widgets
+// before updating our own palettes
+class QGtkStyleUpdateScheduler : public QObject
+{
+ Q_OBJECT
+public slots:
+ void updateTheme();
+};
+
QT_END_NAMESPACE
#endif // !QT_NO_STYLE_GTK
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index 103e97f..b7fa575 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -38,7 +38,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "qgtkstyle.h"
#if !defined(QT_NO_STYLE_GTK)
@@ -138,6 +137,30 @@ static const char * const dock_widget_restore_xpm[] =
};
+class QGtkStyleFilter : public QObject
+{
+public:
+ QGtkStyleFilter() {
+ qApp->installEventFilter(this);
+ }
+
+private:
+ bool eventFilter(QObject *obj, QEvent *e);
+};
+
+bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e)
+{
+ if (e->type() == QEvent::ApplicationPaletteChange) {
+ // Only do this the first time since this will also
+ // generate applicationPaletteChange events
+ extern QHash<QByteArray, QPalette> *qt_app_palettes_hash(); //qapplication.cpp
+ if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
+ QGtk::applyCustomPaletteHash();
+ }
+ }
+ return QObject::eventFilter(obj, e);
+}
+
class QGtkStylePrivate : public QCleanlooksStylePrivate
{
Q_DECLARE_PUBLIC(QGtkStyle)
@@ -145,6 +168,7 @@ public:
QGtkStylePrivate()
: QCleanlooksStylePrivate()
{}
+ QGtkStyleFilter filter;
};
static const int groupBoxBottomMargin = 2; // space below the groupbox
@@ -217,6 +241,7 @@ static QString uniqueName(const QString &key, const QStyleOption *option, const
Constructs a QGtkStyle object.
*/
QGtkStyle::QGtkStyle()
+ : QCleanlooksStyle(*new QGtkStylePrivate)
{
QGtk::initGtkWidgets();
}
@@ -313,7 +338,7 @@ void QGtkStyle::polish(QPalette &palette)
if (!QGtk::isThemeAvailable())
QCleanlooksStyle::polish(palette);
else
- palette = standardPalette();
+ palette = palette.resolve(standardPalette());
}
/*!
@@ -328,6 +353,7 @@ void QGtkStyle::polish(QApplication *app)
if (app->desktopSettingsAware() && QGtk::isThemeAvailable()) {
QApplicationPrivate::setSystemPalette(standardPalette());
QApplicationPrivate::setSystemFont(QGtk::getThemeFont());
+ QGtk::applyCustomPaletteHash();
if (!QGtk::isKDE4Session()) {
qt_filedialog_open_filename_hook = &QGtk::openFilename;
qt_filedialog_save_filename_hook = &QGtk::saveFilename;
@@ -357,12 +383,12 @@ void QGtkStyle::unpolish(QApplication *app)
/*!
\reimp
*/
+
void QGtkStyle::polish(QWidget *widget)
{
QCleanlooksStyle::polish(widget);
if (!QGtk::isThemeAvailable())
return;
-
if (qobject_cast<QAbstractButton*>(widget)
|| qobject_cast<QToolButton*>(widget)
|| qobject_cast<QComboBox*>(widget)
@@ -375,8 +401,6 @@ void QGtkStyle::polish(QWidget *widget)
widget->setAttribute(Qt::WA_Hover);
else if (QTreeView *tree = qobject_cast<QTreeView *> (widget))
tree->viewport()->setAttribute(Qt::WA_Hover);
-
- QGtk::applyGtkSystemPalette(widget);
}
/*!
@@ -399,6 +423,17 @@ int QGtkStyle::pixelMetric(PixelMetric metric,
return QCleanlooksStyle::pixelMetric(metric, option, widget);
switch (metric) {
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QFrame*>(widget)) {
+ if (GtkStyle *style =
+ QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(),
+ "*.GtkScrolledWindow",
+ "*.GtkScrolledWindow",
+ Q_GTK_TYPE_WINDOW))
+ return qMax(style->xthickness, style->ythickness);
+ }
+ return 2;
+
case PM_MenuButtonIndicator:
return 20;
@@ -635,6 +670,66 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
QGtkPainter gtkPainter(painter);
switch (element) {
+ case PE_Frame: {
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *option;
+ copy.state |= State_Raised;
+ drawPrimitive(PE_PanelMenu, &copy, painter, widget);
+ break;
+ }
+ // Drawing the entire itemview frame is very expensive, especially on the native X11 engine
+ // Instead we cheat a bit and draw a border image without the center part, hence only scaling
+ // thin rectangular images
+ const int pmSize = 64;
+ const int border = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ const QString pmKey = QString(QLS("windowframe %0")).arg(option->state);
+
+ QPixmap pixmap;
+ QPixmapCache::find(pmKey, pixmap);
+ QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize));
+
+ // Only draw through style once
+ if (pixmap.isNull()) {
+ pixmap = QPixmap(pmSize, pmSize);
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter gtkFramePainter(&pmPainter);
+ gtkFramePainter.setUsePixmapCache(false); // Don't cache twice
+
+ GtkShadowType shadow_type = GTK_SHADOW_NONE;
+ if (option->state & State_Sunken)
+ shadow_type = GTK_SHADOW_IN;
+ else if (option->state & State_Raised)
+ shadow_type = GTK_SHADOW_OUT;
+
+ GtkStyle *style = QGtk::gtk_rc_get_style_by_paths(QGtk::gtk_settings_get_default(),
+ "*.GtkScrolledWindow", "*.GtkScrolledWindow", Q_GTK_TYPE_WINDOW);
+ if (style)
+ gtkFramePainter.paintShadow(QGtk::gtkWidget(QLS("GtkFrame")), "viewport", pmRect,
+ option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ shadow_type, style);
+ QPixmapCache::insert(pmKey, pixmap);
+ }
+
+ QRect rect = option->rect;
+ const int rw = rect.width() - border;
+ const int rh = rect.height() - border;
+ const int pw = pmRect.width() - border;
+ const int ph = pmRect.height() - border;
+
+ // Sidelines
+ painter->drawPixmap(rect.adjusted(border, 0, -border, -rh), pixmap, pmRect.adjusted(border, 0, -border,-ph));
+ painter->drawPixmap(rect.adjusted(border, rh, -border, 0), pixmap, pmRect.adjusted(border, ph,-border,0));
+ painter->drawPixmap(rect.adjusted(0, border, -rw, -border), pixmap, pmRect.adjusted(0, border, -pw, -border));
+ painter->drawPixmap(rect.adjusted(rw, border, 0, -border), pixmap, pmRect.adjusted(pw, border, 0, -border));
+
+ // Corners
+ painter->drawPixmap(rect.adjusted(0, 0, -rw, -rh), pixmap, pmRect.adjusted(0, 0, -pw,-ph));
+ painter->drawPixmap(rect.adjusted(rw, 0, 0, -rh), pixmap, pmRect.adjusted(pw, 0, 0,-ph));
+ painter->drawPixmap(rect.adjusted(0, rh, -rw, 0), pixmap, pmRect.adjusted(0, ph, -pw,0));
+ painter->drawPixmap(rect.adjusted(rw, rh, 0, 0), pixmap, pmRect.adjusted(pw, ph, 0,0));
+ }
+ break;
case PE_PanelTipLabel: {
GtkWidget *gtkWindow = QGtk::gtkWidget(QLS("GtkWindow")); // The Murrine Engine currently assumes a widget is passed
@@ -882,7 +977,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- painter->fillRect(textRect, option->palette.base().color());
+ painter->fillRect(textRect, option->palette.base());
else
gtkPainter.paintFlatBox( gtkEntry, "entry_bg", textRect,
option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, gtkEntry->style);
@@ -2412,6 +2507,10 @@ void QGtkStyle::drawControl(ControlElement element,
if (selected) {
QRect rect = option->rect.adjusted(0, 0, -1, -1);
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox*>(widget))
+ rect = option->rect;
+#endif
gtkPainter.paintBox( gtkMenuItem, "menuitem", rect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style);
}
@@ -2528,16 +2627,24 @@ void QGtkStyle::drawControl(ControlElement element,
opt.rect = vCheckRect;
drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
}
-
painter->drawPixmap(pmr.topLeft(), pixmap);
}
GdkColor gdkText = gtkMenuItem->style->fg[GTK_STATE_NORMAL];
GdkColor gdkDText = gtkMenuItem->style->fg[GTK_STATE_INSENSITIVE];
GdkColor gdkHText = gtkMenuItem->style->fg[GTK_STATE_PRELIGHT];
+ uint resolve_mask = option->palette.resolve();
QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
QColor disabledTextColor = QColor(gdkDText.red>>8, gdkDText.green>>8, gdkDText.blue>>8);
+ if (resolve_mask & (1 << QPalette::ButtonText)) {
+ textColor = option->palette.buttonText().color();
+ disabledTextColor = option->palette.brush(QPalette::Disabled, QPalette::ButtonText).color();
+ }
+
QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
+ if (resolve_mask & (1 << QPalette::HighlightedText)) {
+ highlightedTextColor = option->palette.highlightedText().color();
+ }
if (selected)
painter->setPen(highlightedTextColor);
@@ -2653,10 +2760,13 @@ void QGtkStyle::drawControl(ControlElement element,
if (tab->state & State_Selected)
state = GTK_STATE_NORMAL;
- bool first = tab->position == QStyleOptionTab::Beginning || tab->position == QStyleOptionTab::OnlyOneTab;
- bool last = tab->position == QStyleOptionTab::End || tab->position == QStyleOptionTab::OnlyOneTab;
bool selected = (tab->state & State_Selected);
- if (option->direction == Qt::RightToLeft) {
+ bool first = false, last = false;
+ if (widget) {
+ // This is most accurate and avoids resizing tabs while moving
+ first = tab->rect.left() == widget->rect().left();
+ last = tab->rect.right() == widget->rect().right();
+ } else if (option->direction == Qt::RightToLeft) {
bool tmp = first;
first = last;
last = tmp;
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 2634d44..398e11d 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -529,6 +529,7 @@ public:
QPointer<QFocusFrame> focusWidget;
CFAbsoluteTime defaultButtonStart;
QMacStyle *q;
+ bool mouseDown;
};
QT_BEGIN_INCLUDE_NAMESPACE
@@ -1477,7 +1478,7 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti
#endif
QMacStylePrivate::QMacStylePrivate(QMacStyle *style)
- : timerID(-1), progressFrame(0), q(style)
+ : timerID(-1), progressFrame(0), q(style), mouseDown(false)
{
defaultButtonStart = CFAbsoluteTimeGetCurrent();
memset(&buttonState, 0, sizeof(ButtonState));
@@ -1494,7 +1495,7 @@ bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget *
{
if (as == AquaPushButton) {
QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
- if (w->window()->isActiveWindow() && pb) {
+ if (w->window()->isActiveWindow() && pb && !mouseDown) {
if (static_cast<const QPushButton *>(w) != defaultButton) {
// Changed on its own, update the value.
const_cast<QMacStylePrivate *>(this)->stopAnimate(as, defaultButton);
@@ -1514,8 +1515,7 @@ void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QWidget *w)
if (as == AquaPushButton && defaultButton) {
QPushButton *tmp = defaultButton;
defaultButton = 0;
- if (tmp->isVisible())
- tmp->update();
+ tmp->update();
} else if (as == AquaProgressBar) {
progressBars.removeAll(w);
}
@@ -1841,10 +1841,15 @@ bool QMacStylePrivate::eventFilter(QObject *o, QEvent *e)
break;
case QEvent::MouseButtonPress:
// It is very confusing to keep the button pulsing, so just stop the animation.
+ if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
+ mouseDown = true;
stopAnimate(AquaPushButton, btn);
break;
- case QEvent::FocusOut:
case QEvent::MouseButtonRelease:
+ if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
+ mouseDown = false;
+ // fall through
+ case QEvent::FocusOut:
case QEvent::Show:
case QEvent::WindowActivate: {
QList<QPushButton *> list = qFindChildren<QPushButton *>(btn->window());
@@ -2184,7 +2189,7 @@ void QMacStyle::polish(QWidget* w)
}
if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
- w->setWindowOpacity(0.94);
+ w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94);
if (!w->testAttribute(Qt::WA_SetPalette)) {
QPixmap px(64, 64);
HIThemeMenuDrawInfo mtinfo;
@@ -3849,13 +3854,16 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
break;
case CE_TabBarTabShape:
- if (const QStyleOptionTabV3 *tabOpt = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
- if (tabOpt->documentMode) {
- p->save();
- QRect tabRect = tabOpt->rect;
- drawTabShape(p, tabOpt);
- p->restore();
- return;
+ if (const QStyleOptionTab *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+
+ if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ if (tabOptV3->documentMode) {
+ p->save();
+ QRect tabRect = tabOptV3->rect;
+ drawTabShape(p, tabOptV3);
+ p->restore();
+ return;
+ }
}
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index f42792d..49ac57a 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1514,20 +1514,11 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette
void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const QWidget *w, bool embedded)
{
-#ifdef QT_NO_COMBOBOX
- const bool isReadOnlyCombo = false;
-#else
- const bool isReadOnlyCombo = qobject_cast<const QComboBox *>(w) != 0;
-#endif
-
if (bg && bg->brush.style() != Qt::NoBrush) {
- if (isReadOnlyCombo) {
- p->setBrush(cg, QPalette::Base, bg->brush); // for windows, windowxp
- p->setBrush(cg, QPalette::Button, bg->brush); // for plastique
- } else {
- p->setBrush(cg, w->backgroundRole(), bg->brush);
- //p->setBrush(cg, QPalette::Window, bg->brush);
- }
+ p->setBrush(cg, QPalette::Base, bg->brush); // for windows, windowxp
+ p->setBrush(cg, QPalette::Button, bg->brush); // for plastique
+ p->setBrush(cg, w->backgroundRole(), bg->brush);
+ p->setBrush(cg, QPalette::Window, bg->brush);
}
if (embedded) {
@@ -1542,12 +1533,9 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
return;
if (pal->foreground.style() != Qt::NoBrush) {
- if (isReadOnlyCombo) {
- p->setBrush(cg, QPalette::ButtonText, pal->foreground);
- } else {
- p->setBrush(cg, w->foregroundRole(), pal->foreground);
- p->setBrush(cg, QPalette::WindowText, pal->foreground);
- }
+ p->setBrush(cg, QPalette::ButtonText, pal->foreground);
+ p->setBrush(cg, w->foregroundRole(), pal->foreground);
+ p->setBrush(cg, QPalette::WindowText, pal->foreground);
p->setBrush(cg, QPalette::Text, pal->foreground);
}
if (pal->selectionBackground.style() != Qt::NoBrush)
@@ -2916,6 +2904,10 @@ void QStyleSheetStyle::polish(QWidget *w)
if (ew->autoFillBackground()) {
ew->setAutoFillBackground(false);
autoFillDisabledWidgets->insert(w);
+ if (ew != w) { //eg. viewport of a scrollarea
+ //(in order to draw the background anyway in case we don't.)
+ ew->setAttribute(Qt::WA_StyledBackground, true);
+ }
}
if (!rule.hasBackground() || rule.background()->isTransparent() || rule.hasBox()
|| (!rule.hasNativeBorder() && !rule.border()->isOpaque()))
@@ -4345,8 +4337,16 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
return;
case PE_Widget:
- if (!rule.hasBackground())
+ if (!rule.hasBackground()) {
+ QWidget *container = containerWidget(w);
+ if (autoFillDisabledWidgets->contains(container)
+ && (container == w || !renderRule(container, opt).hasBackground())) {
+ //we do not have a background, but we disabled the autofillbackground anyway. so fill the background now.
+ // (this may happen if we have rules like :focus)
+ p->fillRect(opt->rect, opt->palette.brush(w->backgroundRole()));
+ }
break;
+ }
#ifndef QT_NO_SCROLLAREA
if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w)) {
@@ -4623,15 +4623,6 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
break;
case PM_DefaultFrameWidth:
-#ifndef QT_NO_COMBOBOX
- // QComboBox uses this for resizing its popup
- if (qobject_cast<const QComboBox *>(w)) {
- QAbstractItemView *view = qFindChild<QAbstractItemView *>(w);
- QRenderRule subRule = renderRule(view, PseudoElement_None);
- if (!subRule.hasNativeBorder())
- return subRule.border()->borders[TopEdge] + (subRule.hasBox() ? subRule.box()->paddings[TopEdge] : 0);
- } else
-#endif
if (!rule.hasNativeBorder())
return rule.border()->borders[LeftEdge];
break;
@@ -4849,7 +4840,8 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
if (subRule.hasContentsSize())
return subRule.size().height();
else if (subRule.hasBox() || subRule.hasBorder()) {
- return subRule.size(QSize(0, opt->fontMetrics.lineSpacing())).height();
+ QFontMetrics fm = opt ? opt->fontMetrics : w->fontMetrics();
+ return subRule.size(QSize(0, fm.lineSpacing())).height();
}
break;
}
diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp
index c52c700..1c03b9e 100644
--- a/src/gui/styles/qwindowsmobilestyle.cpp
+++ b/src/gui/styles/qwindowsmobilestyle.cpp
@@ -3401,6 +3401,9 @@ int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, cons
case SH_ScrollBar_ContextMenu:
ret = false;
break;
+ case SH_MenuBar_AltKeyNavigation:
+ ret = false;
+ break;
default:
ret = QWindowsStyle::styleHint(hint, opt, widget, returnData);
break;
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
index 4c3060d..013ca1e 100644
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ b/src/gui/styles/qwindowsvistastyle.cpp
@@ -801,12 +801,20 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
|| vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
painter->drawPixmap(pixmapRect.topLeft(), pixmap);
- else if (reverse ? rightSection : leftSection)
- painter->drawPixmap(pixmapRect, pixmap, srcRect.adjusted(0, 0, -frame, 0));
- else if (reverse ? leftSection : rightSection)
- painter->drawPixmap(pixmapRect, pixmap,
- srcRect.adjusted(frame, 0, 0, 0));
- else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle)
+ else if (reverse ? rightSection : leftSection){
+ painter->drawPixmap(QRect(pixmapRect.topLeft(),
+ QSize(frame, pixmapRect.height())), pixmap,
+ QRect(QPoint(0, 0), QSize(frame, pixmapRect.height())));
+ painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0),
+ pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+ } else if (reverse ? leftSection : rightSection) {
+ painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0),
+ QSize(frame, pixmapRect.height())), pixmap,
+ QRect(QPoint(pixmapRect.width() - frame, 0),
+ QSize(frame, pixmapRect.height())));
+ painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0),
+ pixmap, srcRect.adjusted(frame, 0, -frame, 0));
+ } else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle)
painter->drawPixmap(pixmapRect, pixmap,
srcRect.adjusted(frame, 0, -frame, 0));
} else {
@@ -2388,6 +2396,9 @@ void QWindowsVistaStyle::polish(QWidget *widget)
else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
tree->viewport()->setAttribute(Qt::WA_Hover);
}
+ else if (QListView *list = qobject_cast<QListView *> (widget)) {
+ list->viewport()->setAttribute(Qt::WA_Hover);
+ }
}
/*!
diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h
index 877bc50..cef2b71 100644
--- a/src/gui/styles/qwindowsvistastyle_p.h
+++ b/src/gui/styles/qwindowsvistastyle_p.h
@@ -76,6 +76,7 @@
#include <qscrollbar.h>
#include <qprogressbar.h>
#include <qdockwidget.h>
+#include <qlistview.h>
#include <qtreeview.h>
#include <qtextedit.h>
#include <qmessagebox.h>
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
index 9d735a7..2f4254e 100644
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ b/src/gui/styles/qwindowsxpstyle.cpp
@@ -607,7 +607,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
QPainter *painter = themeData.painter;
Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
- if (!painter)
+ if (!painter || !painter->isActive())
return;
painter->save();
@@ -2834,7 +2834,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
bflags |= State_MouseOver;
}
}
-
+
QStyleOption tool(0);
tool.palette = toolbutton->palette;
if (toolbutton->subControls & SC_ToolButton) {
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 02fe2b2..db1e781 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -2682,7 +2682,10 @@ bool Parser::parseFunction(QString *name, QString *args)
bool Parser::parseHexColor(QColor *col)
{
col->setNamedColor(lexem());
- if (!col->isValid()) return false;
+ if (!col->isValid()) {
+ qWarning("QCssParser::parseHexColor: Unknown color name '%s'",lexem().toLatin1().constData());
+ return false;
+ }
skipSpace();
return true;
}
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 8538040..43f5b1e 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -249,9 +249,10 @@ QFontPrivate::~QFontPrivate()
}
#if !defined(Q_WS_MAC)
+extern QMutex *qt_fontdatabase_mutex();
+
QFontEngine *QFontPrivate::engineForScript(int script) const
{
- extern QMutex *qt_fontdatabase_mutex();
QMutexLocker locker(qt_fontdatabase_mutex());
if (script >= QUnicodeTables::Inherited)
script = QUnicodeTables::Common;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index c4dffdf..47fe5c2 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -542,7 +542,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
advanceY += glyphs.advances_y[i];
continue;
}
- QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);
+ const QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);
const int w = alphaMask.width();
const int h = alphaMask.height();
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 264d8de..cb0b436 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -521,15 +521,28 @@ QFontEngineFT::Glyph::~Glyph()
delete [] data;
}
-#if !defined(QT_USE_FREETYPE_LCDFILTER)
static const uint subpixel_filter[3][3] = {
{ 180, 60, 16 },
{ 38, 180, 38 },
{ 16, 60, 180 }
};
-#endif
-static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
+static inline uint filterPixel(uint red, uint green, uint blue, bool legacyFilter)
+{
+ uint res;
+ if (legacyFilter) {
+ uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8;
+ uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8;
+ uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8;
+ res = (mid << 24) + (high << 16) + (mid << 8) + low;
+ } else {
+ uint alpha = green;
+ res = (alpha << 24) + (red << 16) + (green << 8) + blue;
+ }
+ return res;
+}
+
+static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
{
int h = height;
const int offs = bgr ? -1 : 1;
@@ -540,9 +553,7 @@ static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height,
uint red = src[x+1-offs];
uint green = src[x+1];
uint blue = src[x+1+offs];
- uint alpha = green;
- uint res = (alpha << 24) + (red << 16) + (green << 8) + blue;
- *dd = res;
+ *dd = filterPixel(red, green, blue, legacyFilter);
++dd;
}
dst += width;
@@ -550,7 +561,7 @@ static void convertRGBToARGB(const uchar *src, uint *dst, int width, int height,
}
}
-static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
+static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
{
int h = height;
const int offs = bgr ? -src_pitch : src_pitch;
@@ -559,16 +570,7 @@ static void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int heigh
uint red = src[x+src_pitch-offs];
uint green = src[x+src_pitch];
uint blue = src[x+src_pitch+offs];
-#if defined(QT_USE_FREETYPE_LCDFILTER)
- uint alpha = green;
- uint res = (alpha << 24) + (red << 16) + (green << 8) + blue;
-#else
- uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8;
- uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8;
- uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8;
- uint res = (mid << 24) + (high << 16) + (mid << 8) + low;
-#endif
- dst[x] = res;
+ dst[x] = filterPixel(red, green, blue, legacyFilter);
}
dst += width;
src += 3*src_pitch;
@@ -923,8 +925,14 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
uchar *glyph_buffer = 0;
int glyph_buffer_size = 0;
#if defined(QT_USE_FREETYPE_LCDFILTER)
+ bool useFreetypeRenderGlyph = false;
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
- FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType);
+ err = FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType);
+ if (err == FT_Err_Ok)
+ useFreetypeRenderGlyph = true;
+ }
+
+ if (useFreetypeRenderGlyph) {
err = FT_Render_Glyph(slot, hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V);
if (err != FT_Err_Ok)
@@ -932,8 +940,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
FT_Library_SetLcdFilter(library, FT_LCD_FILTER_NONE);
- info.height = slot->bitmap.rows;
- info.width = slot->bitmap.width / 3;
+ info.height = slot->bitmap.rows / vfactor;
+ info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width;
info.x = -slot->bitmap_left;
info.y = slot->bitmap_top;
@@ -941,9 +949,9 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
glyph_buffer = new uchar[glyph_buffer_size];
if (hsubpixel)
- convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_RGB);
+ convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_RGB, false);
else if (vfactor != 1)
- convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_VRGB);
+ convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_VRGB, false);
} else
#endif
{
@@ -1042,11 +1050,19 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
Q_ASSERT(antialias);
uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch];
- convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
- convertRGBToARGB(convoluted + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_RGB);
+ bool useLegacyLcdFilter = false;
+#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
+ useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
+#endif
+ uchar *buffer = bitmap.buffer;
+ if (!useLegacyLcdFilter) {
+ convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
+ buffer = convoluted;
+ }
+ convertRGBToARGB(buffer + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_RGB, useLegacyLcdFilter);
delete [] convoluted;
} else if (vfactor != 1) {
- convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_VRGB);
+ convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != QFontEngineFT::Subpixel_VRGB, true);
}
if (bitmap.buffer != glyph_buffer)
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 40d145a..425cab2 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -120,7 +120,7 @@ OSStatus QMacFontPath::closePath(void *data)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
@@ -149,11 +149,15 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con
CFRetain(ctfont);
}
- const void *keys[] = { NSFontAttributeName };
- const void *values[] = { ctfont };
- attributeDict = CFDictionaryCreate(0, keys, values, 1,
+ attributeDict = CFDictionaryCreateMutable(0, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont);
+ if (!kerning) {
+ float zero = 0.0;
+ QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
+ CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern);
+ }
QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this);
fe->ref.ref();
@@ -277,10 +281,11 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y);
}
- double runWidth = ceil(CTRunGetTypographicBounds(run, range, 0, 0, 0));
- runWidth += tmpPoints[0].x;
+ CGSize lastGlyphAdvance;
+ CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
+
outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
- outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(runWidth - tmpPoints[glyphCount - 1].x);
+ outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width).ceil();
}
outGlyphs += glyphCount;
outAttributes += glyphCount;
@@ -365,26 +370,26 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
CGSize advances[1];
CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1);
- ret.xoff = QFixed::fromReal(advances[0].width);
- ret.yoff = QFixed::fromReal(advances[0].height);
+ ret.xoff = QFixed::fromReal(advances[0].width).ceil();
+ ret.yoff = QFixed::fromReal(advances[0].height).ceil();
return ret;
}
QFixed QCoreTextFontEngine::ascent() const
{
- return QFixed::fromReal(CTFontGetAscent(ctfont));
+ return QFixed::fromReal(CTFontGetAscent(ctfont)).ceil();
}
QFixed QCoreTextFontEngine::descent() const
{
- return QFixed::fromReal(CTFontGetDescent(ctfont));
+ return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
}
QFixed QCoreTextFontEngine::leading() const
{
- return QFixed::fromReal(CTFontGetLeading(ctfont));
+ return QFixed::fromReal(CTFontGetLeading(ctfont)).ceil();
}
QFixed QCoreTextFontEngine::xHeight() const
{
- return QFixed::fromReal(CTFontGetXHeight(ctfont));
+ return QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil();
}
QFixed QCoreTextFontEngine::averageCharWidth() const
{
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index e289aa9..176c728 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -480,7 +480,7 @@ private:
uint fontIndexForFont(CTFontRef id) const;
CTFontRef ctfont;
- mutable QCFType<CFDictionaryRef> attributeDict;
+ mutable QCFType<CFMutableDictionaryRef> attributeDict;
friend class QFontDialogPrivate;
};
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index e9f1c99..1996d44 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -1438,6 +1438,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin
extern bool qt_cleartype_enabled;
+extern uint qt_pow_gamma[256];
QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
{
@@ -1461,8 +1462,6 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
colors[i] = qRgba(0, 0, 0, i);
indexed.setColorTable(colors);
- extern uint qt_pow_gamma[256];
-
// Copy data... Cannot use QPainter here as GDI has messed up the
// Alpha channel of the ni.image pixels...
for (int y=0; y<mask->height(); ++y) {
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index c337783..9c3d6c2 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -287,6 +287,7 @@ public:
private:
Q_DISABLE_COPY(QTextDocument)
Q_DECLARE_PRIVATE(QTextDocument)
+ friend class QTextObjectPrivate;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextDocument::FindFlags)
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 320ecbf..05ddf47 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -1484,7 +1484,6 @@ QTextObject *QTextDocumentPrivate::createObject(const QTextFormat &f, int object
QTextObject *obj = document()->createObject(f);
if (obj) {
- obj->d_func()->pieceTable = this;
obj->d_func()->objectIndex = objectIndex == -1 ? formats.createObjectIndex(f) : objectIndex;
objects[obj->d_func()->objectIndex] = obj;
}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 86a1f68..b1f1b75 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1525,6 +1525,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
node->charFormat.setFontFamily(value);
} else if (key == QLatin1String("color")) {
QColor c; c.setNamedColor(value);
+ if (!c.isValid())
+ qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
node->charFormat.setForeground(c);
}
break;
@@ -1570,6 +1572,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
case Html_body:
if (key == QLatin1String("bgcolor")) {
QColor c; c.setNamedColor(value);
+ if (!c.isValid())
+ qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
node->charFormat.setBackground(c);
} else if (key == QLatin1String("background")) {
node->applyBackgroundImage(value, resourceProvider);
@@ -1581,6 +1585,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
setWidthAttribute(&node->width, value);
} else if (key == QLatin1String("bgcolor")) {
QColor c; c.setNamedColor(value);
+ if (!c.isValid())
+ qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
node->charFormat.setBackground(c);
} else if (key == QLatin1String("background")) {
node->applyBackgroundImage(value, resourceProvider);
@@ -1597,6 +1603,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
setFloatAttribute(&node->tableBorder, value);
} else if (key == QLatin1String("bgcolor")) {
QColor c; c.setNamedColor(value);
+ if (!c.isValid())
+ qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
node->charFormat.setBackground(c);
} else if (key == QLatin1String("background")) {
node->applyBackgroundImage(value, resourceProvider);
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index e305027..d1a3361 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -50,6 +50,11 @@ QT_BEGIN_NAMESPACE
class QTextListPrivate : public QTextBlockGroupPrivate
{
+public:
+ QTextListPrivate(QTextDocument *doc)
+ : QTextBlockGroupPrivate(doc)
+ {
+ }
};
/*!
@@ -111,7 +116,7 @@ class QTextListPrivate : public QTextBlockGroupPrivate
/*! \internal
*/
QTextList::QTextList(QTextDocument *doc)
- : QTextBlockGroup(*new QTextListPrivate, doc)
+ : QTextBlockGroup(*new QTextListPrivate(doc), doc)
{
}
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index 1645a21..3f4c8e5 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -88,7 +88,7 @@ QT_BEGIN_NAMESPACE
from QTextDocument::createObject().
*/
QTextObject::QTextObject(QTextDocument *doc)
- : QObject(*new QTextObjectPrivate, doc)
+ : QObject(*new QTextObjectPrivate(doc), doc)
{
}
@@ -98,7 +98,7 @@ QTextObject::QTextObject(QTextDocument *doc)
\internal
*/
QTextObject::QTextObject(QTextObjectPrivate &p, QTextDocument *doc)
- :QObject(p, doc)
+ : QObject(p, doc)
{
}
@@ -221,7 +221,7 @@ void QTextBlockGroupPrivate::markBlocksDirty()
QTextDocument::createObject().
*/
QTextBlockGroup::QTextBlockGroup(QTextDocument *doc)
- : QTextObject(*new QTextBlockGroupPrivate, doc)
+ : QTextObject(*new QTextBlockGroupPrivate(doc), doc)
{
}
@@ -410,7 +410,7 @@ QTextFrameLayoutData::~QTextFrameLayoutData()
Creates a new empty frame for the text \a document.
*/
QTextFrame::QTextFrame(QTextDocument *doc)
- : QTextObject(*new QTextFramePrivate, doc)
+ : QTextObject(*new QTextFramePrivate(doc), doc)
{
Q_D(QTextFrame);
d->fragment_start = 0;
diff --git a/src/gui/text/qtextobject_p.h b/src/gui/text/qtextobject_p.h
index b00a16a..dd05eb4 100644
--- a/src/gui/text/qtextobject_p.h
+++ b/src/gui/text/qtextobject_p.h
@@ -55,6 +55,7 @@
#include "QtGui/qtextobject.h"
#include "private/qobject_p.h"
+#include "QtGui/qtextdocument.h"
QT_BEGIN_NAMESPACE
@@ -64,6 +65,10 @@ class QTextObjectPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QTextObject)
public:
+ QTextObjectPrivate(QTextDocument *doc)
+ : pieceTable(doc->d_func()), objectIndex(-1)
+ {
+ }
QTextDocumentPrivate *pieceTable;
int objectIndex;
};
@@ -72,7 +77,10 @@ class QTextBlockGroupPrivate : public QTextObjectPrivate
{
Q_DECLARE_PUBLIC(QTextBlockGroup)
public:
-
+ QTextBlockGroupPrivate(QTextDocument *doc)
+ : QTextObjectPrivate(doc)
+ {
+ }
typedef QList<QTextBlock> BlockList;
BlockList blocks;
void markBlocksDirty();
@@ -85,7 +93,10 @@ class QTextFramePrivate : public QTextObjectPrivate
friend class QTextDocumentPrivate;
Q_DECLARE_PUBLIC(QTextFrame)
public:
-
+ QTextFramePrivate(QTextDocument *doc)
+ : QTextObjectPrivate(doc)
+ {
+ }
virtual void fragmentAdded(const QChar &type, uint fragment);
virtual void fragmentRemoved(const QChar &type, uint fragment);
void remove_me();
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index 375bb09..ba1c04f 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -553,7 +553,7 @@ void QTextTablePrivate::update() const
/*! \internal
*/
QTextTable::QTextTable(QTextDocument *doc)
- : QTextFrame(*new QTextTablePrivate, doc)
+ : QTextFrame(*new QTextTablePrivate(doc), doc)
{
}
diff --git a/src/gui/text/qtexttable_p.h b/src/gui/text/qtexttable_p.h
index 1ba3a3f..f2b45b6 100644
--- a/src/gui/text/qtexttable_p.h
+++ b/src/gui/text/qtexttable_p.h
@@ -62,7 +62,7 @@ class QTextTablePrivate : public QTextFramePrivate
{
Q_DECLARE_PUBLIC(QTextTable)
public:
- QTextTablePrivate() : grid(0), nRows(0), dirty(true), blockFragmentUpdates(false) {}
+ QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), nRows(0), dirty(true), blockFragmentUpdates(false) {}
~QTextTablePrivate();
static QTextTable *createTable(QTextDocumentPrivate *, int pos, int rows, int cols, const QTextTableFormat &tableFormat);
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
index 8b07163..7571dfe 100644
--- a/src/gui/util/qcompleter.cpp
+++ b/src/gui/util/qcompleter.cpp
@@ -824,9 +824,9 @@ void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted)
Q_Q(QCompleter);
QString completion;
- if (!index.isValid())
+ if (!index.isValid() || (index.row() >= proxy->engine->matchCount())) {
completion = prefix;
- else {
+ } else {
QModelIndex si = proxy->mapToSource(index);
si = si.sibling(si.row(), column); // for clicked()
completion = q->pathFromIndex(si);
@@ -1079,7 +1079,14 @@ void QCompleter::setPopup(QAbstractItemView *popup)
popup->setModel(d->proxy);
popup->hide();
popup->setParent(0, Qt::Popup);
+
+ Qt::FocusPolicy origPolicy;
+ if (d->widget)
+ origPolicy = d->widget->focusPolicy();
popup->setFocusPolicy(Qt::NoFocus);
+ if (d->widget)
+ d->widget->setFocusPolicy(origPolicy);
+
popup->setFocusProxy(d->widget);
popup->installEventFilter(this);
popup->setItemDelegate(new QCompleterItemDelegate(popup));
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 1056fa0..84aa16e 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -157,6 +157,11 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
If the URL is a reference to a local file (i.e., the URL scheme is "file") then
it will be opened with a suitable application instead of a Web browser.
+ The following example opens a file on the Windows file system residing on a path
+ that contains spaces:
+
+ \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 2
+
If a \c mailto URL is specified, the user's e-mail client will be used to open a
composer window containing the options specified in the URL, similar to the way
\c mailto links are handled by a Web browser.
@@ -280,6 +285,17 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme)
\note The storage location returned can be a directory that does not exist; i.e., it
may need to be created by the system or the user.
+
+ \note On Mac OS X, DataLocation does not include QCoreApplication::organizationName.
+ Use code like this to add it:
+
+ \code
+ QString location = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ #ifdef Q_WS_MAC
+ location.insert(location.count() - QCoreApplication::applicationName().count(),
+ QCoreApplication::organizationName() + "/");
+ #endif
+ \endcode
*/
/*!
diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp
index 330a7f8..61ed0ea 100644
--- a/src/gui/widgets/qabstractbutton.cpp
+++ b/src/gui/widgets/qabstractbutton.cpp
@@ -1248,15 +1248,6 @@ void QAbstractButton::timerEvent(QTimerEvent *e)
}
}
-#if defined(Q_OS_WINCE) && !defined(QT_NO_CONTEXTMENU)
-/*! \reimp */
-void QAbstractButton::contextMenuEvent(QContextMenuEvent *e)
-{
- e->ignore();
- setDown(false);
-}
-#endif
-
/*! \reimp */
void QAbstractButton::focusInEvent(QFocusEvent *e)
{
diff --git a/src/gui/widgets/qabstractbutton.h b/src/gui/widgets/qabstractbutton.h
index 6503a56..f0cbb05 100644
--- a/src/gui/widgets/qabstractbutton.h
+++ b/src/gui/widgets/qabstractbutton.h
@@ -143,9 +143,6 @@ protected:
void focusOutEvent(QFocusEvent *e);
void changeEvent(QEvent *e);
void timerEvent(QTimerEvent *e);
-#ifdef Q_OS_WINCE
- void contextMenuEvent(QContextMenuEvent *e);
-#endif
#ifdef QT3_SUPPORT
public:
diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm
index c5977e4..6434289 100644
--- a/src/gui/widgets/qcocoamenu_mac.mm
+++ b/src/gui/widgets/qcocoamenu_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#include "qmacdefines_mac.h"
#include "qapplication.h"
@@ -55,6 +55,16 @@
QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QWidget)
QT_FORWARD_DECLARE_CLASS(QApplication)
+QT_FORWARD_DECLARE_CLASS(QCoreApplication)
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
+QT_FORWARD_DECLARE_CLASS(QKeyEvent)
+QT_FORWARD_DECLARE_CLASS(QEvent)
+
+QT_BEGIN_NAMESPACE
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(QCocoaMenu)
@@ -130,8 +140,9 @@ QT_FORWARD_DECLARE_CLASS(QApplication)
// If it does, then we will first send the key sequence to the QWidget that has focus
// since (in Qt's eyes) it needs to a chance at the key event first. If the widget
// accepts the key event, we then return YES, but set the target and action to be nil,
- // which means that the action should not be triggered. In every other case we return
- // NO, which means that Cocoa can do as it pleases (i.e., fire the menu action).
+ // which means that the action should not be triggered, and instead dispatch the event ourselves.
+ // In every other case we return NO, which means that Cocoa can do as it pleases
+ // (i.e., fire the menu action).
NSMenuItem *whichItem;
if ([self hasShortcut:menu
forKey:[event characters]
@@ -154,9 +165,11 @@ QT_FORWARD_DECLARE_CLASS(QApplication)
accel_ev.ignore();
qt_sendSpontaneousEvent(widget, &accel_ev);
if (accel_ev.isAccepted()) {
- *target = nil;
- *action = nil;
- return YES;
+ if (qt_dispatchKeyEvent(event, widget)) {
+ *target = nil;
+ *action = nil;
+ return YES;
+ }
}
}
}
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 75b8b59..09a51fe 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -61,6 +61,7 @@
#endif
#include <private/qcombobox_p.h>
#include <private/qabstractitemmodel_p.h>
+#include <private/qabstractscrollarea_p.h>
#include <qdebug.h>
#ifdef Q_WS_X11
@@ -108,7 +109,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
const QModelIndex &index) const
{
QStyleOptionMenuItem menuOption;
- menuOption.palette = QComboBoxPrivate::viewContainerPalette(mCombo).resolve(QApplication::palette("QMenu"));
+ menuOption.palette = option.palette.resolve(QApplication::palette("QMenu"));
menuOption.state = QStyle::State_None;
if (mCombo->window()->isActiveWindow())
menuOption.state = QStyle::State_Active;
@@ -619,7 +620,6 @@ void QComboBoxPrivateContainer::changeEvent(QEvent *e)
bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
{
switch (e->type()) {
- case QEvent::KeyPress:
case QEvent::ShortcutOverride:
switch (static_cast<QKeyEvent*>(e)->key()) {
case Qt::Key_Enter:
@@ -2274,7 +2274,6 @@ void QComboBox::showPopup()
bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen);
const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
-
{
int listHeight = 0;
int count = 0;
@@ -2306,10 +2305,23 @@ void QComboBox::showPopup()
listRect.setHeight(listHeight);
}
- // ### Adjusting by PM_DefaultFrameWidth is not enough. Since QFrame supports
- // SE_FrameContents, QFrame needs API to return the frameWidths
- listRect.setHeight(listRect.height() + 2*container->spacing()
- + style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this) * 2);
+ {
+ // add the spacing for the grid on the top and the bottom;
+ int heightMargin = 2*container->spacing();
+
+ // add the frame of the container
+ int marginTop, marginBottom;
+ container->getContentsMargins(0, &marginTop, 0, &marginBottom);
+ heightMargin += marginTop + marginBottom;
+
+ //add the frame of the view
+ view()->getContentsMargins(0, &marginTop, 0, &marginBottom);
+ marginTop += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->top;
+ marginBottom += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->bottom;
+ heightMargin += marginTop + marginBottom;
+
+ listRect.setHeight(listRect.height() + heightMargin);
+ }
// Add space for margin at top and bottom if the style wants it.
if (usePopup)
@@ -2322,6 +2334,8 @@ void QComboBox::showPopup()
listRect.setWidth(listRect.width() + diff);
}
+ //we need to activate the layout to make sure the min/maximum size are set when the widget was not yet show
+ container->layout()->activate();
//takes account of the minimum/maximum size of the container
listRect.setSize( listRect.size().expandedTo(container->minimumSize())
.boundedTo(container->maximumSize()));
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index f1203dc..c39a231 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -265,7 +265,7 @@ protected:
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
QStyleOptionMenuItem opt = getStyleOption(option, index);
- painter->eraseRect(option.rect);
+ painter->fillRect(option.rect, opt.palette.background());
mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
}
QSize sizeHint(const QStyleOptionViewItem &option,
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 246da95..4a95292 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -752,7 +752,8 @@ QDialogButtonBox::~QDialogButtonBox()
\value KdeLayout Use a policy appropriate for applications on KDE.
\value GnomeLayout Use a policy appropriate for applications on GNOME.
- The button layout is specified by the \l{style()}{current style}.
+ The button layout is specified by the \l{style()}{current style}. However,
+ on the X11 platform, it may be influenced by the desktop environment.
*/
/*!
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 9261c63..4f0ec1e 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -579,7 +579,7 @@ void QDockAreaLayoutInfo::fitItems()
QLayoutStruct &ls = layout_struct_list[j++];
ls.init();
ls.empty = false;
- if (gap || (item.flags & QDockAreaLayoutItem::KeepSize)) {
+ if (item.flags & QDockAreaLayoutItem::KeepSize) {
ls.minimumSize = ls.maximumSize = ls.sizeHint = item.size;
ls.expansive = false;
ls.stretch = 0;
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
index 5ff7bf5..a5be5f8 100644
--- a/src/gui/widgets/qdockwidget.cpp
+++ b/src/gui/widgets/qdockwidget.cpp
@@ -292,8 +292,11 @@ QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) co
if (content.height() < 0)
result.setHeight(-1);
- QSize min = w->minimumSize();
- QSize max = w->maximumSize();
+ int left, top, right, bottom;
+ w->getContentsMargins(&left, &top, &right, &bottom);
+ //we need to substract the contents margin (it will be added by the caller)
+ QSize min = w->minimumSize() - QSize(left + right, top + bottom);
+ QSize max = w->maximumSize() - QSize(left + right, top + bottom);
/* A floating dockwidget will automatically get its minimumSize set to the layout's
minimum size + deco. We're *not* interested in this, we only take minimumSize()
@@ -403,10 +406,14 @@ int QDockWidgetLayout::minimumTitleWidth() const
QSize closeSize(0, 0);
QSize floatSize(0, 0);
- if (QLayoutItem *item = item_list[CloseButton])
- closeSize = item->sizeHint();
- if (QLayoutItem *item = item_list[FloatButton])
- floatSize = item->sizeHint();
+ if (hasFeature(q, QDockWidget::DockWidgetClosable)) {
+ if (QLayoutItem *item = item_list[CloseButton])
+ closeSize = item->widget()->sizeHint();
+ }
+ if (hasFeature(q, QDockWidget::DockWidgetFloatable)) {
+ if (QLayoutItem *item = item_list[FloatButton])
+ floatSize = item->widget()->sizeHint();
+ }
int titleHeight = this->titleHeight();
diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm
index 710af6a..380e983 100644
--- a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm
+++ b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <private/qwidget_p.h>
diff --git a/src/gui/widgets/qmacnativewidget_mac.mm b/src/gui/widgets/qmacnativewidget_mac.mm
index 1bc0430..0f4edf9 100644
--- a/src/gui/widgets/qmacnativewidget_mac.mm
+++ b/src/gui/widgets/qmacnativewidget_mac.mm
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** 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
@@ -36,11 +36,11 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <private/qcocoaview_mac_p.h>
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 46d6471..2abc9e8 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -481,7 +481,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
oldMenuBar->deleteLater();
}
#ifdef Q_OS_WINCE
- if (menuBar->size().height() > 0)
+ if (menuBar && menuBar->size().height() > 0)
#endif
d->layout->setMenuBar(menuBar);
}
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 768446e..eade633 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -1542,8 +1542,8 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
if (!previousPath.isEmpty())
layoutState.remove(previousPath);
+ pluggingWidget = widget;
if (dockOptions & QMainWindow::AnimatedDocks) {
- pluggingWidget = widget;
QRect globalRect = currentGapRect;
globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft()));
#ifndef QT_NO_DOCKWIDGET
@@ -1575,6 +1575,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
#endif
currentGapPos.clear();
updateGapIndicator();
+ pluggingWidget = 0;
}
return true;
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 950f758..c807afb 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -1,3 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
#include <private/qmainwindowlayout_p.h>
#include <qtoolbar.h>
#include <private/qtoolbarlayout_p.h>
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index e96856a..7396a9d 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -578,7 +578,8 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
//when the action has no QWidget, the QMenu itself should
// get the focus
// Since the menu is a pop-up, it uses the popup reason.
- q->setFocus(Qt::PopupFocusReason);
+ if (!q->hasFocus())
+ q->setFocus(Qt::PopupFocusReason);
}
}
} else { //action is a separator
@@ -2888,8 +2889,8 @@ void QMenu::internalDelayedPopup()
int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);
const QRect actionRect(d->actionRect(d->currentAction));
const QSize menuSize(d->activeMenu->sizeHint());
- const QPoint rightPos(mapToGlobal(QPoint(rect().right() + subMenuOffset + 1, actionRect.top())));
- const QPoint leftPos(mapToGlobal(QPoint(rect().left() - subMenuOffset - menuSize.width(), actionRect.top())));
+ const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top())));
+ const QPoint leftPos(mapToGlobal(QPoint(actionRect.left() - subMenuOffset - menuSize.width(), actionRect.top())));
QPoint pos(rightPos);
QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget);
diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp
index fc9e1a3..9bfe7a5 100644
--- a/src/gui/widgets/qscrollbar.cpp
+++ b/src/gui/widgets/qscrollbar.cpp
@@ -444,26 +444,19 @@ void QScrollBar::contextMenuEvent(QContextMenuEvent *event)
#ifndef QT_NO_MENU
bool horiz = HORIZONTAL;
- QMenu menu;
- QAction *actScrollHere =
- menu.addAction(tr("Scroll here"));
- menu.addSeparator();
- QAction *actScrollTop =
- menu.addAction(horiz ? tr("Left edge") : tr("Top"));
- QAction *actScrollBottom =
- menu.addAction(horiz ? tr("Right edge") : tr("Bottom"));
- menu.addSeparator();
- QAction *actPageUp =
- menu.addAction(horiz ? tr("Page left") : tr("Page up"));
- QAction *actPageDn =
- menu.addAction(horiz ? tr("Page right") : tr("Page down"));
- menu.addSeparator();
- QAction *actScrollUp =
- menu.addAction(horiz ? tr("Scroll left") : tr("Scroll up"));
- QAction *actScrollDn =
- menu.addAction(horiz ? tr("Scroll right") : tr("Scroll down"));
-
- QAction *actionSelected = menu.exec(event->globalPos());
+ QPointer<QMenu> menu = new QMenu(this);
+ QAction *actScrollHere = menu->addAction(tr("Scroll here"));
+ menu->addSeparator();
+ QAction *actScrollTop = menu->addAction(horiz ? tr("Left edge") : tr("Top"));
+ QAction *actScrollBottom = menu->addAction(horiz ? tr("Right edge") : tr("Bottom"));
+ menu->addSeparator();
+ QAction *actPageUp = menu->addAction(horiz ? tr("Page left") : tr("Page up"));
+ QAction *actPageDn = menu->addAction(horiz ? tr("Page right") : tr("Page down"));
+ menu->addSeparator();
+ QAction *actScrollUp = menu->addAction(horiz ? tr("Scroll left") : tr("Scroll up"));
+ QAction *actScrollDn = menu->addAction(horiz ? tr("Scroll right") : tr("Scroll down"));
+ QAction *actionSelected = menu->exec(event->globalPos());
+ delete menu;
if (actionSelected == 0)
/* do nothing */ ;
else if (actionSelected == actScrollHere)
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 7d970ad..b6e6b6d 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -131,7 +131,7 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
option->state &= ~QStyle::State_Enabled;
if (isActiveWindow())
option->state |= QStyle::State_Active;
- if (option->rect == d->hoverRect)
+ if (!d->dragInProgress && option->rect == d->hoverRect)
option->state |= QStyle::State_MouseOver;
option->shape = d->shape;
option->text = tab.text;
@@ -454,9 +454,6 @@ void QTabBarPrivate::layoutTabs()
maxExtent = maxWidth;
}
- if (pressedIndex != -1 && movable)
- grabCache(0, tabList.count(), true);
-
Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure.
// Mirror our front item.
tabChain[tabChainIndex].init();
@@ -1484,6 +1481,8 @@ void QTabBar::paintEvent(QPaintEvent *)
bool vertical = verticalTabs(d->shape);
QStyleOptionTab cutTab;
selected = d->currentIndex;
+ if (d->dragInProgress)
+ selected = d->pressedIndex;
for (int i = 0; i < d->tabList.count(); ++i)
optTabBase.tabBarRect |= tabRect(i);
@@ -1522,11 +1521,7 @@ void QTabBar::paintEvent(QPaintEvent *)
if (i == selected)
continue;
- if (!d->tabList[i].animatingCache.isNull() && d->paintWithOffsets) {
- p.drawPixmap(tab.rect, d->tabList[i].animatingCache);
- } else {
- p.drawControl(QStyle::CE_TabBarTab, tab);
- }
+ p.drawControl(QStyle::CE_TabBarTab, tab);
}
// Draw the selected tab last to get it "on top"
@@ -1539,7 +1534,11 @@ void QTabBar::paintEvent(QPaintEvent *)
else
tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset);
}
- p.drawControl(QStyle::CE_TabBarTab, tab);
+ if (!d->dragInProgress)
+ p.drawControl(QStyle::CE_TabBarTab, tab);
+ else
+ d->movingTab->setGeometry(tab.rect);
+
}
// Only draw the tear indicator if necessary. Most of the time we don't need too.
@@ -1680,6 +1679,7 @@ void QTabBarPrivate::_q_moveTab(int offset)
if (!validIndex(index))
return;
tabList[index].dragOffset = offset;
+ layoutTab(index); // Make buttons follow tab
q->update();
}
}
@@ -1727,8 +1727,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
if (!d->dragInProgress && d->pressedIndex != -1) {
if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) {
d->dragInProgress = true;
- if (d->animations.isEmpty())
- d->grabCache(0, d->tabList.count(), false);
+ d->setupMovableTab();
}
}
@@ -1773,7 +1772,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
if (dragDistance > needsToBeOver)
d->slide(i + offset, d->pressedIndex);
}
-
}
// Buttons needs to follow the dragged tab
d->layoutTab(d->pressedIndex);
@@ -1801,32 +1799,41 @@ void QTabBarPrivate::_q_moveTabFinished()
}
}
-void QTabBarPrivate::grabCache(int start, int end, bool unhide)
+void QTabBarPrivate::setupMovableTab()
{
Q_Q(QTabBar);
- paintWithOffsets = false;
- bool showButtonsAgain = rightB->isVisible();
- rightB->hide();
- leftB->hide();
-
- QWidget *topLevel = q->window();
- QPoint topLevelOffset(q->mapTo(topLevel, QPoint()));
- for (int i = start; i < end; ++i) {
- QRect tabRect = q->tabRect(i);
- tabRect.translate(topLevelOffset);
- if (unhide) {
- tabList[i].unHideWidgets();
- layoutWidgets(i);
- }
- tabList[i].animatingCache = QPixmap::grabWidget(topLevel, tabRect);
- if (i != pressedIndex)
- tabList[i].hideWidgets();
- }
- if (showButtonsAgain) {
- rightB->show();
- leftB->show();
- }
- paintWithOffsets = true;
+ if (!movingTab)
+ movingTab = new QWidget(q);
+
+ QRect grabRect = q->tabRect(pressedIndex);
+
+ QPixmap grabImage(grabRect.size());
+ grabImage.fill(Qt::transparent);
+ QStylePainter p(&grabImage, q);
+
+ QStyleOptionTabV3 tab;
+ q->initStyleOption(&tab, pressedIndex);
+ tab.rect.moveTopLeft(QPoint(0, 0));
+ p.drawControl(QStyle::CE_TabBarTab, tab);
+ p.end();
+
+ QPalette pal;
+ pal.setBrush(QPalette::All, QPalette::Window, grabImage);
+ movingTab->setPalette(pal);
+ movingTab->setGeometry(grabRect);
+ movingTab->setAutoFillBackground(true);
+ movingTab->raise();
+
+ // Re-arrange widget order to avoid overlaps
+ if (tabList[pressedIndex].leftWidget)
+ tabList[pressedIndex].leftWidget->raise();
+ if (tabList[pressedIndex].rightWidget)
+ tabList[pressedIndex].rightWidget->raise();
+ if (leftB)
+ leftB->raise();
+ if (rightB)
+ rightB->raise();
+ movingTab->setVisible(true);
}
void QTabBarPrivate::_q_moveTabFinished(int index)
@@ -1834,10 +1841,9 @@ void QTabBarPrivate::_q_moveTabFinished(int index)
Q_Q(QTabBar);
bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
if (animations.isEmpty() && cleanup) {
+ movingTab->setVisible(false); // We might not get a mouse release
for (int i = 0; i < tabList.count(); ++i) {
tabList[i].dragOffset = 0;
- tabList[i].unHideWidgets();
- tabList[i].animatingCache = QPixmap();
}
if (pressedIndex != -1 && movable) {
pressedIndex = -1;
@@ -1881,6 +1887,7 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event)
d->_q_moveTabFinished(d->pressedIndex);
}
d->dragInProgress = false;
+ d->movingTab->setVisible(false);
d->dragStartPosition = QPoint();
}
@@ -2203,19 +2210,16 @@ void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget)
widget->setParent(this);
// make sure our left and right widgets stay on top
widget->lower();
+ widget->show();
}
if (position == LeftSide) {
if (d->tabList[index].leftWidget)
d->tabList[index].leftWidget->hide();
d->tabList[index].leftWidget = widget;
- if(!d->tabList[index].hidLeft && widget)
- widget->show();
} else {
if (d->tabList[index].rightWidget)
d->tabList[index].rightWidget->hide();
d->tabList[index].rightWidget = widget;
- if(!d->tabList[index].hidRight && widget)
- widget->show();
}
d->layoutTabs();
update();
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index a117aa3..cb1a15b 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -70,7 +70,6 @@
QT_BEGIN_NAMESPACE
-
class QTabBarPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QTabBar)
@@ -78,7 +77,7 @@ public:
QTabBarPrivate()
:currentIndex(-1), pressedIndex(-1),
shape(QTabBar::RoundedNorth),
- layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false) {}
+ layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {}
int currentIndex;
int pressedIndex;
@@ -98,8 +97,6 @@ public:
, lastTab(-1)
, timeLine(0)
, dragOffset(0)
- , hidLeft(false)
- , hidRight(false)
{}
bool enabled;
int shortcutId;
@@ -123,9 +120,6 @@ public:
QTimeLine *timeLine;
int dragOffset;
- QPixmap animatingCache;
- bool hidLeft;
- bool hidRight;
void makeTimeLine(QWidget *q) {
if (timeLine)
@@ -135,27 +129,6 @@ public:
q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished()));
}
- void hideWidgets() {
- if (!hidRight && rightWidget) {
- hidRight = rightWidget->isVisible();
- rightWidget->hide();
- }
-
- if (!hidLeft && leftWidget) {
- hidLeft = leftWidget->isVisible();
- leftWidget->hide();
- }
- }
-
- void unHideWidgets() {
- if (leftWidget && hidLeft)
- leftWidget->show();
- hidLeft = false;
- if (rightWidget && hidRight)
- rightWidget->show();
- hidRight = false;
- }
-
};
QList<Tab> tabList;
QHash<QTimeLine*, int> animations;
@@ -184,12 +157,12 @@ public:
void _q_moveTabFinished(int offset);
QRect hoverRect;
- void grabCache(int start, int end, bool unhide);
void refresh();
void layoutTabs();
void layoutWidgets(int index = -1);
void layoutTab(int index);
void updateMacBorderMetrics();
+ void setupMovableTab();
void makeVisible(int index);
QSize iconSize;
@@ -206,6 +179,8 @@ public:
bool dragInProgress;
bool documentMode;
+ QWidget *movingTab;
+
// shared by tabwidget and qtabbar
static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size)
{
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index b239e32..1c4df93 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -1478,7 +1478,13 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
layout->setViewport(QRect());
}
-/*! \reimp
+/*! \fn void QTextEdit::paintEvent(QPaintEvent *event)
+
+This event handler can be reimplemented in a subclass to receive paint events passed in \a event.
+It is usually unnecessary to reimplement this function in a subclass of QTextEdit.
+
+\warning The underlying text document must not be modified from within a reimplementation
+of this function.
*/
void QTextEdit::paintEvent(QPaintEvent *e)
{
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index 85d6ea2..1babb6d 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -1153,6 +1153,17 @@ bool QToolBar::event(QEvent *event)
if (d->mouseMoveEvent(static_cast<QMouseEvent*>(event)))
return true;
break;
+#ifdef Q_OS_WINCE
+ case QEvent::ContextMenu:
+ {
+ QContextMenuEvent* contextMenuEvent = static_cast<QContextMenuEvent*>(event);
+ QWidget* child = childAt(contextMenuEvent->pos());
+ QAbstractButton* button = qobject_cast<QAbstractButton*>(child);
+ if (button)
+ button->setDown(false);
+ }
+ break;
+#endif
case QEvent::Leave:
if (d->state != 0 && d->state->dragging) {
#ifdef Q_OS_WIN
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index 6bcca0c..3269b2e 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -2,6 +2,9 @@
HEADERS += access/qftp.h \
access/qhttp.h \
+ access/qhttpnetworkheader_p.h \
+ access/qhttpnetworkrequest_p.h \
+ access/qhttpnetworkreply_p.h \
access/qhttpnetworkconnection_p.h \
access/qnetworkaccessmanager.h \
access/qnetworkaccessmanager_p.h \
@@ -27,6 +30,9 @@ HEADERS += access/qftp.h \
SOURCES += access/qftp.cpp \
access/qhttp.cpp \
+ access/qhttpnetworkheader.cpp \
+ access/qhttpnetworkrequest.cpp \
+ access/qhttpnetworkreply.cpp \
access/qhttpnetworkconnection.cpp \
access/qnetworkaccessmanager.cpp \
access/qnetworkaccesscache.cpp \
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp
index 0141ae2..96ccc91 100644
--- a/src/network/access/qhttp.cpp
+++ b/src/network/access/qhttp.cpp
@@ -2120,6 +2120,10 @@ int QHttp::setUser(const QString &userName, const QString &password)
Web proxy cache server (from \l http://www.squid.org/). For transparent
proxying, such as SOCKS5, use QNetworkProxy instead.
+ \note setProxy() has to be called before setHost() for it to take effect.
+ If setProxy() is called after setHost(), then it will not apply until after
+ setHost() is called again.
+
\sa QFtp::setProxy()
*/
int QHttp::setProxy(const QString &host, int port,
@@ -2139,7 +2143,7 @@ int QHttp::setProxy(const QString &host, int port,
is QNetworkProxy::HttpCachingProxy, QHttp will behave like the
previous function.
- Note: for compatibility with Qt 4.3, if the proxy type is
+ \note for compatibility with Qt 4.3, if the proxy type is
QNetworkProxy::HttpProxy and the request type is unencrypted (that
is, ConnectionModeHttp), QHttp will treat the proxy as a caching
proxy.
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index edb2988..980c0e0 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -45,7 +45,7 @@
#include <private/qauthenticator_p.h>
#include <qnetworkproxy.h>
#include <qauthenticator.h>
-#include <qbytearraymatcher.h>
+
#include <qbuffer.h>
#include <qpair.h>
#include <qhttp.h>
@@ -59,875 +59,9 @@
# include <QtNetwork/qsslconfiguration.h>
#endif
-#ifndef QT_NO_COMPRESS
-# include <zlib.h>
-static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header
-// gzip flag byte
-#define HEAD_CRC 0x02 // bit 1 set: header CRC present
-#define EXTRA_FIELD 0x04 // bit 2 set: extra field present
-#define ORIG_NAME 0x08 // bit 3 set: original file name present
-#define COMMENT 0x10 // bit 4 set: file comment present
-#define RESERVED 0xE0 // bits 5..7: reserved
-#define CHUNK 16384
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QHttpNetworkHeaderPrivate : public QSharedData
-{
-public:
- QUrl url;
- QList<QPair<QByteArray, QByteArray> > fields;
-
- QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl());
- QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other);
- inline qint64 contentLength() const;
- inline void setContentLength(qint64 length);
-
- inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
- inline QList<QByteArray> headerFieldValues(const QByteArray &name) const;
- inline void setHeaderField(const QByteArray &name, const QByteArray &data);
- bool operator==(const QHttpNetworkHeaderPrivate &other) const;
-
-};
-
-QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl)
- :url(newUrl)
-{
-}
-
-QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other)
- :QSharedData(other)
-{
- url = other.url;
- fields = other.fields;
-}
-
-qint64 QHttpNetworkHeaderPrivate::contentLength() const
-{
- bool ok = false;
- QByteArray value = headerField("content-length");
- qint64 length = value.toULongLong(&ok);
- if (ok)
- return length;
- return -1; // the header field is not set
-}
-
-void QHttpNetworkHeaderPrivate::setContentLength(qint64 length)
-{
- setHeaderField("Content-Length", QByteArray::number(length));
-}
-
-QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray &defaultValue) const
-{
- QList<QByteArray> allValues = headerFieldValues(name);
- if (allValues.isEmpty())
- return defaultValue;
-
- QByteArray result;
- bool first = true;
- foreach (QByteArray value, allValues) {
- if (!first)
- result += ", ";
- first = false;
- result += value;
- }
- return result;
-}
-
-QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const
-{
- QList<QByteArray> result;
- QByteArray lowerName = name.toLower();
- QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
- end = fields.constEnd();
- for ( ; it != end; ++it)
- if (lowerName == it->first.toLower())
- result += it->second;
-
- return result;
-}
-
-void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data)
-{
- QByteArray lowerName = name.toLower();
- QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin();
- while (it != fields.end()) {
- if (lowerName == it->first.toLower())
- it = fields.erase(it);
- else
- ++it;
- }
- fields.append(qMakePair(name, data));
-}
-
-bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const
-{
- return (url == other.url);
-}
-
-// QHttpNetworkRequestPrivate
-class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate
-{
-public:
- QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
- QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl());
- QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other);
- ~QHttpNetworkRequestPrivate();
- bool operator==(const QHttpNetworkRequestPrivate &other) const;
- QByteArray methodName() const;
- QByteArray uri(bool throughProxy) const;
-
- static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy);
-
- QHttpNetworkRequest::Operation operation;
- QHttpNetworkRequest::Priority priority;
- mutable QIODevice *data;
- bool autoDecompress;
-};
-
-QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
- QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
- : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), data(0),
- autoDecompress(false)
-{
-}
-
-QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other)
- : QHttpNetworkHeaderPrivate(other)
-{
- operation = other.operation;
- priority = other.priority;
- data = other.data;
- autoDecompress = other.autoDecompress;
-}
-
-QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
-{
-}
-
-bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const
-{
- return QHttpNetworkHeaderPrivate::operator==(other)
- && (operation == other.operation)
- && (data == other.data);
-}
-
-QByteArray QHttpNetworkRequestPrivate::methodName() const
-{
- QByteArray ba;
- switch (operation) {
- case QHttpNetworkRequest::Options:
- ba += "OPTIONS";
- break;
- case QHttpNetworkRequest::Get:
- ba += "GET";
- break;
- case QHttpNetworkRequest::Head:
- ba += "HEAD";
- break;
- case QHttpNetworkRequest::Post:
- ba += "POST";
- break;
- case QHttpNetworkRequest::Put:
- ba += "PUT";
- break;
- case QHttpNetworkRequest::Delete:
- ba += "DELETE";
- break;
- case QHttpNetworkRequest::Trace:
- ba += "TRACE";
- break;
- case QHttpNetworkRequest::Connect:
- ba += "CONNECT";
- break;
- default:
- break;
- }
- return ba;
-}
-
-QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const
-{
- QUrl::FormattingOptions format(QUrl::RemoveFragment);
-
- // for POST, query data is send as content
- if (operation == QHttpNetworkRequest::Post && !data)
- format |= QUrl::RemoveQuery;
- // for requests through proxy, the Request-URI contains full url
- if (throughProxy)
- format |= QUrl::RemoveUserInfo;
- else
- format |= QUrl::RemoveScheme | QUrl::RemoveAuthority;
- QByteArray uri = url.toEncoded(format);
- if (uri.isEmpty() || (throughProxy && url.path().isEmpty()))
- uri += '/';
- return uri;
-}
-
-QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy)
-{
- QByteArray ba = request.d->methodName();
- QByteArray uri = request.d->uri(throughProxy);
- ba += " " + uri;
-
- QString majorVersion = QString::number(request.majorVersion());
- QString minorVersion = QString::number(request.minorVersion());
- ba += " HTTP/" + majorVersion.toLatin1() + "." + minorVersion.toLatin1() + "\r\n";
-
- QList<QPair<QByteArray, QByteArray> > fields = request.header();
- QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin();
- for (; it != fields.constEnd(); ++it)
- ba += it->first + ": " + it->second + "\r\n";
- if (request.d->operation == QHttpNetworkRequest::Post) {
- // add content type, if not set in the request
- if (request.headerField("content-type").isEmpty())
- ba += "Content-Type: application/x-www-form-urlencoded\r\n";
- if (!request.d->data && request.d->url.hasQuery()) {
- QByteArray query = request.d->url.encodedQuery();
- ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n";
- ba += "\r\n";
- ba += query;
- } else {
- ba += "\r\n";
- }
- } else {
- ba += "\r\n";
- }
- return ba;
-}
-
-class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
-{
-public:
- QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl());
- ~QHttpNetworkReplyPrivate();
- qint64 readStatus(QAbstractSocket *socket);
- void parseStatus(const QByteArray &status);
- qint64 readHeader(QAbstractSocket *socket);
- void parseHeader(const QByteArray &header);
- qint64 readBody(QAbstractSocket *socket, QIODevice *out);
- bool findChallenge(bool forProxy, QByteArray &challenge) const;
- QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
- void clear();
-
- qint64 transferRaw(QIODevice *in, QIODevice *out, qint64 size);
- qint64 transferChunked(QIODevice *in, QIODevice *out);
- qint64 getChunkSize(QIODevice *in, qint64 *chunkSize);
-
- qint64 bytesAvailable() const;
- bool isChunked();
- bool connectionCloseEnabled();
- bool isGzipped();
-#ifndef QT_NO_COMPRESS
- bool gzipCheckHeader(QByteArray &content, int &pos);
- int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated);
-#endif
- void removeAutoDecompressHeader();
-
- enum ReplyState {
- NothingDoneState,
- ReadingStatusState,
- ReadingHeaderState,
- ReadingDataState,
- AllDoneState
- } state;
-
- QHttpNetworkRequest request;
- int statusCode;
- int majorVersion;
- int minorVersion;
- QString errorString;
- QString reasonPhrase;
- qint64 bodyLength;
- qint64 contentRead;
- qint64 totalProgress;
- QByteArray fragment;
- qint64 currentChunkSize;
- qint64 currentChunkRead;
- QPointer<QHttpNetworkConnection> connection;
- bool initInflate;
- bool streamEnd;
-#ifndef QT_NO_COMPRESS
- z_stream inflateStrm;
-#endif
- bool autoDecompress;
-
- QByteArray responseData; // uncompressed body
- QByteArray compressedData; // compressed body (temporary)
- QBuffer requestDataBuffer;
- bool requestIsBuffering;
- bool requestIsPrepared;
-};
-
-QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
- : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
- majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
- currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
- autoDecompress(false), requestIsBuffering(false), requestIsPrepared(false)
-{
-}
-
-QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
-{
-}
-
-void QHttpNetworkReplyPrivate::clear()
-{
- state = NothingDoneState;
- statusCode = 100;
- bodyLength = 0;
- contentRead = 0;
- totalProgress = 0;
- currentChunkSize = 0;
- currentChunkRead = 0;
- connection = 0;
-#ifndef QT_NO_COMPRESS
- if (initInflate)
- inflateEnd(&inflateStrm);
-#endif
- initInflate = false;
- streamEnd = false;
- autoDecompress = false;
- fields.clear();
-}
-
-// QHttpNetworkReplyPrivate
-qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
-{
- return (state != ReadingDataState ? 0 : fragment.size());
-}
-
-bool QHttpNetworkReplyPrivate::isGzipped()
-{
- QByteArray encoding = headerField("content-encoding");
- return encoding.toLower() == "gzip";
-}
-
-void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
-{
- // The header "Content-Encoding = gzip" is retained.
- // Content-Length is removed since the actual one send by the server is for compressed data
- QByteArray name("content-length");
- QByteArray lowerName = name.toLower();
- QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
- end = fields.end();
- while (it != end) {
- if (name == it->first.toLower()) {
- fields.erase(it);
- break;
- }
- ++it;
- }
-
-}
-
-bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const
-{
- challenge.clear();
- // find out the type of authentication protocol requested.
- QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate";
- // pick the best protocol (has to match parsing in QAuthenticatorPrivate)
- QList<QByteArray> challenges = headerFieldValues(header);
- for (int i = 0; i<challenges.size(); i++) {
- QByteArray line = challenges.at(i);
- if (!line.toLower().startsWith("negotiate"))
- challenge = line;
- }
- return !challenge.isEmpty();
-}
-
-QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(bool isProxy) const
-{
- // The logic is same as the one used in void QAuthenticatorPrivate::parseHttpResponse()
- QAuthenticatorPrivate::Method method = QAuthenticatorPrivate::None;
- QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
- QList<QByteArray> challenges = headerFieldValues(header);
- for (int i = 0; i<challenges.size(); i++) {
- QByteArray line = challenges.at(i).trimmed().toLower();
- if (method < QAuthenticatorPrivate::Basic
- && line.startsWith("basic")) {
- method = QAuthenticatorPrivate::Basic;
- } else if (method < QAuthenticatorPrivate::Ntlm
- && line.startsWith("ntlm")) {
- method = QAuthenticatorPrivate::Ntlm;
- } else if (method < QAuthenticatorPrivate::DigestMd5
- && line.startsWith("digest")) {
- method = QAuthenticatorPrivate::DigestMd5;
- }
- }
- return method;
-}
-
-#ifndef QT_NO_COMPRESS
-bool QHttpNetworkReplyPrivate::gzipCheckHeader(QByteArray &content, int &pos)
-{
- int method = 0; // method byte
- int flags = 0; // flags byte
- bool ret = false;
-
- // Assure two bytes in the buffer so we can peek ahead -- handle case
- // where first byte of header is at the end of the buffer after the last
- // gzip segment
- pos = -1;
- QByteArray &body = content;
- int maxPos = body.size()-1;
- if (maxPos < 1) {
- return ret;
- }
-
- // Peek ahead to check the gzip magic header
- if (body[0] != char(gz_magic[0]) ||
- body[1] != char(gz_magic[1])) {
- return ret;
- }
- pos += 2;
- // Check the rest of the gzip header
- if (++pos <= maxPos)
- method = body[pos];
- if (pos++ <= maxPos)
- flags = body[pos];
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- return ret;
- }
-
- // Discard time, xflags and OS code:
- pos += 6;
- if (pos > maxPos)
- return ret;
- if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field
- unsigned len = (unsigned)body[++pos];
- len += ((unsigned)body[++pos])<<8;
- pos += len;
- if (pos > maxPos)
- return ret;
- }
- if ((flags & ORIG_NAME) != 0) { // skip the original file name
- while(++pos <= maxPos && body[pos]) {}
- }
- if ((flags & COMMENT) != 0) { // skip the .gz file comment
- while(++pos <= maxPos && body[pos]) {}
- }
- if ((flags & HEAD_CRC) != 0) { // skip the header crc
- pos += 2;
- if (pos > maxPos)
- return ret;
- }
- ret = (pos < maxPos); // return failed, if no more bytes left
- return ret;
-}
-
-int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated)
-{
- int ret = Z_DATA_ERROR;
- unsigned have;
- unsigned char out[CHUNK];
- int pos = -1;
-
- if (!initInflate) {
- // check the header
- if (!gzipCheckHeader(compressed, pos))
- return ret;
- // allocate inflate state
- inflateStrm.zalloc = Z_NULL;
- inflateStrm.zfree = Z_NULL;
- inflateStrm.opaque = Z_NULL;
- inflateStrm.avail_in = 0;
- inflateStrm.next_in = Z_NULL;
- ret = inflateInit2(&inflateStrm, -MAX_WBITS);
- if (ret != Z_OK)
- return ret;
- initInflate = true;
- streamEnd = false;
- }
-
- //remove the header.
- compressed.remove(0, pos+1);
- // expand until deflate stream ends
- inflateStrm.next_in = (unsigned char *)compressed.data();
- inflateStrm.avail_in = compressed.size();
- do {
- inflateStrm.avail_out = sizeof(out);
- inflateStrm.next_out = out;
- ret = inflate(&inflateStrm, Z_NO_FLUSH);
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR;
- // and fall through
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- inflateEnd(&inflateStrm);
- initInflate = false;
- return ret;
- }
- have = sizeof(out) - inflateStrm.avail_out;
- inflated.append(QByteArray((const char *)out, have));
- } while (inflateStrm.avail_out == 0);
- // clean up and return
- if (ret <= Z_ERRNO || ret == Z_STREAM_END) {
- inflateEnd(&inflateStrm);
- initInflate = false;
- }
- streamEnd = (ret == Z_STREAM_END);
- return ret;
-}
-#endif
-
-qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
-{
- qint64 bytes = 0;
- char c;
-
- while (socket->bytesAvailable()) {
- // allow both CRLF & LF (only) line endings
- if (socket->peek(&c, 1) == 1 && c == '\n') {
- bytes += socket->read(&c, 1); // read the "n"
- // remove the CR at the end
- if (fragment.endsWith('\r')) {
- fragment.truncate(fragment.length()-1);
- }
- parseStatus(fragment);
- state = ReadingHeaderState;
- fragment.clear(); // next fragment
- break;
- } else {
- c = 0;
- bytes += socket->read(&c, 1);
- fragment.append(c);
- }
- }
- return bytes;
-}
-
-void QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status)
-{
- const QByteArrayMatcher sp(" ");
- int i = sp.indexIn(status);
- const QByteArray version = status.mid(0, i);
- int j = sp.indexIn(status, i + 1);
- const QByteArray code = status.mid(i + 1, j - i - 1);
- const QByteArray reason = status.mid(j + 1, status.count() - j);
-
- const QByteArrayMatcher slash("/");
- int k = slash.indexIn(version);
- const QByteArrayMatcher dot(".");
- int l = dot.indexIn(version, k);
- const QByteArray major = version.mid(k + 1, l - k - 1);
- const QByteArray minor = version.mid(l + 1, version.count() - l);
-
- majorVersion = QString::fromAscii(major.constData()).toInt();
- minorVersion = QString::fromAscii(minor.constData()).toInt();
- statusCode = QString::fromAscii(code.constData()).toInt();
- reasonPhrase = QString::fromAscii(reason.constData());
-}
-
-qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
-{
- qint64 bytes = 0;
- char crlfcrlf[5];
- crlfcrlf[4] = '\0';
- char c = 0;
- bool allHeaders = false;
- while (!allHeaders && socket->bytesAvailable()) {
- if (socket->peek(&c, 1) == 1 && c == '\n') {
- // check for possible header endings. As per HTTP rfc,
- // the header endings will be marked by CRLFCRLF. But
- // we will allow CRLFLF, LFLF & CRLFCRLF
- if (fragment.endsWith("\n\r") || fragment.endsWith('\n'))
- allHeaders = true;
- }
- bytes += socket->read(&c, 1);
- fragment.append(c);
- }
- // we received all headers now parse them
- if (allHeaders) {
- parseHeader(fragment);
- state = ReadingDataState;
- fragment.clear(); // next fragment
- bodyLength = contentLength(); // cache the length
- }
- return bytes;
-}
-
-void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header)
-{
- // see rfc2616, sec 4 for information about HTTP/1.1 headers.
- // allows relaxed parsing here, accepts both CRLF & LF line endings
- const QByteArrayMatcher lf("\n");
- const QByteArrayMatcher colon(":");
- int i = 0;
- while (i < header.count()) {
- int j = colon.indexIn(header, i); // field-name
- if (j == -1)
- break;
- const QByteArray field = header.mid(i, j - i).trimmed();
- j++;
- // any number of LWS is allowed before and after the value
- QByteArray value;
- do {
- i = lf.indexIn(header, j);
- if (i == -1)
- break;
- if (!value.isEmpty())
- value += ' ';
- // check if we have CRLF or only LF
- bool hasCR = (i && header[i-1] == '\r');
- int length = i -(hasCR ? 1: 0) - j;
- value += header.mid(j, length).trimmed();
- j = ++i;
- } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t'));
- if (i == -1)
- break; // something is wrong
-
- fields.append(qMakePair(field, value));
- }
-}
-
-bool QHttpNetworkReplyPrivate::isChunked()
-{
- return headerField("transfer-encoding").toLower().contains("chunked");
-}
-
-bool QHttpNetworkReplyPrivate::connectionCloseEnabled()
-{
- return (headerField("connection").toLower().contains("close") ||
- headerField("proxy-connection").toLower().contains("close"));
-}
-
-qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QIODevice *out)
-{
- qint64 bytes = 0;
- if (isChunked()) {
- bytes += transferChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6)
- } else if (bodyLength > 0) { // we have a Content-Length
- bytes += transferRaw(socket, out, bodyLength - contentRead);
- if (contentRead + bytes == bodyLength)
- state = AllDoneState;
- } else {
- bytes += transferRaw(socket, out, socket->bytesAvailable());
- }
- if (state == AllDoneState)
- socket->readAll(); // Read the rest to clean (CRLF)
- contentRead += bytes;
- return bytes;
-}
-
-qint64 QHttpNetworkReplyPrivate::transferRaw(QIODevice *in, QIODevice *out, qint64 size)
-{
- qint64 bytes = 0;
- Q_ASSERT(in);
- Q_ASSERT(out);
-
- int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, in->bytesAvailable()));
- QByteArray raw(toBeRead, 0);
- while (size > 0) {
- qint64 read = in->read(raw.data(), raw.size());
- if (read == 0)
- return bytes;
- // ### error checking here
- qint64 written = out->write(raw.data(), read);
- if (written == 0)
- return bytes;
- if (read != written)
- qDebug() << "### read" << read << "written" << written;
- bytes += read;
- size -= read;
- out->waitForBytesWritten(-1); // throttle
- }
- return bytes;
-
-}
-
-qint64 QHttpNetworkReplyPrivate::transferChunked(QIODevice *in, QIODevice *out)
-{
- qint64 bytes = 0;
- while (in->bytesAvailable()) { // while we can read from input
- // if we are done with the current chunk, get the size of the new chunk
- if (currentChunkRead >= currentChunkSize) {
- currentChunkSize = 0;
- currentChunkRead = 0;
- if (bytes) {
- char crlf[2];
- bytes += in->read(crlf, 2); // read the "\r\n" after the chunk
- }
- bytes += getChunkSize(in, &currentChunkSize);
- if (currentChunkSize == -1)
- break;
- }
- // if the chunk size is 0, end of the stream
- if (currentChunkSize == 0) {
- state = AllDoneState;
- break;
- }
- // otherwise, read data
- qint64 readSize = qMin(in->bytesAvailable(), currentChunkSize - currentChunkRead);
- QByteArray buffer(readSize, 0);
- qint64 read = in->read(buffer.data(), readSize);
- bytes += read;
- currentChunkRead += read;
- qint64 written = out->write(buffer);
- Q_UNUSED(written); // Avoid compile warning when building release
- Q_ASSERT(read == written);
- // ### error checking here
- out->waitForBytesWritten(-1);
- }
- return bytes;
-}
-
-qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize)
-{
- qint64 bytes = 0;
- char crlf[2];
- *chunkSize = -1;
- int bytesAvailable = in->bytesAvailable();
- while (bytesAvailable > bytes) {
- qint64 sniffedBytes = in->peek(crlf, 2);
- int fragmentSize = fragment.size();
- // check the next two bytes for a "\r\n", skip blank lines
- if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n')
- ||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n'))
- {
- bytes += in->read(crlf, 1); // read the \r or \n
- if (crlf[0] == '\r')
- bytes += in->read(crlf, 1); // read the \n
- bool ok = false;
- // ignore the chunk-extension
- fragment = fragment.mid(0, fragment.indexOf(';')).trimmed();
- *chunkSize = fragment.toLong(&ok, 16);
- fragment.clear();
- break; // size done
- } else {
- // read the fragment to the buffer
- char c = 0;
- bytes += in->read(&c, 1);
- fragment.append(c);
- }
- }
- return bytes;
-}
-
-// QHttpNetworkConnectionPrivate
-
-typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
-
-class QHttpNetworkConnectionPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QHttpNetworkConnection)
-public:
- QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
- ~QHttpNetworkConnectionPrivate();
- void init();
- void connectSignals(QAbstractSocket *socket);
-
- enum SocketState {
- IdleState = 0, // ready to send request
- ConnectingState = 1, // connecting to host
- WritingState = 2, // writing the data
- WaitingState = 4, // waiting for reply
- ReadingState = 8, // reading the reply
- Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done
- BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState)
- };
-
- enum { ChunkSize = 4096 };
-
- int indexOf(QAbstractSocket *socket) const;
- bool isSocketBusy(QAbstractSocket *socket) const;
- bool isSocketWriting(QAbstractSocket *socket) const;
- bool isSocketWaiting(QAbstractSocket *socket) const;
- bool isSocketReading(QAbstractSocket *socket) const;
-
- QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
- void unqueueRequest(QAbstractSocket *socket);
- void prepareRequest(HttpMessagePair &request);
- bool sendRequest(QAbstractSocket *socket);
- void receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply);
- void resendCurrentRequest(QAbstractSocket *socket);
- void closeChannel(int channel);
- void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
-
- // private slots
- void _q_bytesWritten(qint64 bytes); // proceed sending
- void _q_readyRead(); // pending data to read
- void _q_disconnected(); // disconnected from host
- void _q_startNextRequest(); // send the next request from the queue
- void _q_restartPendingRequest(); // send the currently blocked request
- void _q_connected(); // start sending request
- void _q_error(QAbstractSocket::SocketError); // error from socket
-#ifndef QT_NO_NETWORKPROXY
- void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
-#endif
- void _q_dataReadyReadNoBuffer();
- void _q_dataReadyReadBuffer();
-
- void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
- bool ensureConnection(QAbstractSocket *socket);
- QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket);
- void eraseData(QHttpNetworkReply *reply);
-#ifndef QT_NO_COMPRESS
- bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete);
-#endif
- void bufferData(HttpMessagePair &request);
- void removeReply(QHttpNetworkReply *reply);
-
- QString hostName;
- quint16 port;
- bool encrypt;
-
- struct Channel {
- QAbstractSocket *socket;
- SocketState state;
- QHttpNetworkRequest request; // current request
- QHttpNetworkReply *reply; // current reply for this request
- qint64 written;
- qint64 bytesTotal;
- bool resendCurrent;
- int lastStatus; // last status received on this channel
- bool pendingEncrypt; // for https (send after encrypted)
- int reconnectAttempts; // maximum 2 reconnection attempts
- QAuthenticatorPrivate::Method authMehtod;
- QAuthenticatorPrivate::Method proxyAuthMehtod;
- QAuthenticator authenticator;
- QAuthenticator proxyAuthenticator;
-#ifndef QT_NO_OPENSSL
- bool ignoreSSLErrors;
-#endif
- Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2),
- authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None)
-#ifndef QT_NO_OPENSSL
- , ignoreSSLErrors(false)
-#endif
- {}
- };
- static const int channelCount;
- Channel channels[2]; // maximum of 2 socket connections to the server
- bool pendingAuthSignal; // there is an incomplete authentication signal
- bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal
-
- void appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed);
- qint64 bytesAvailable(const QHttpNetworkReply &reply, bool compressed = false) const;
- qint64 read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed);
- void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
- bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
- void allDone(QAbstractSocket *socket, QHttpNetworkReply *reply);
- void handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply);
- inline bool emitSignals(QHttpNetworkReply *reply);
- inline bool expectContent(QHttpNetworkReply *reply);
-
-#ifndef QT_NO_OPENSSL
- void _q_encrypted(); // start sending request (https)
- void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
- QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const;
-#endif
-#ifndef QT_NO_NETWORKPROXY
- QNetworkProxy networkProxy;
-#endif
- //The request queues
- QList<HttpMessagePair> highPriorityQueue;
- QList<HttpMessagePair> lowPriorityQueue;
-};
+QT_BEGIN_NAMESPACE
const int QHttpNetworkConnectionPrivate::channelCount = 2;
@@ -2150,235 +1284,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const
}
#endif
-// QHttpNetworkRequest
-
-QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority)
- : d(new QHttpNetworkRequestPrivate(operation, priority, url))
-{
-}
-
-QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other)
- : QHttpNetworkHeader(other), d(other.d)
-{
-}
-
-QHttpNetworkRequest::~QHttpNetworkRequest()
-{
-}
-
-QUrl QHttpNetworkRequest::url() const
-{
- return d->url;
-}
-void QHttpNetworkRequest::setUrl(const QUrl &url)
-{
- d->url = url;
-}
-
-qint64 QHttpNetworkRequest::contentLength() const
-{
- return d->contentLength();
-}
-
-void QHttpNetworkRequest::setContentLength(qint64 length)
-{
- d->setContentLength(length);
-}
-
-QList<QPair<QByteArray, QByteArray> > QHttpNetworkRequest::header() const
-{
- return d->fields;
-}
-
-QByteArray QHttpNetworkRequest::headerField(const QByteArray &name, const QByteArray &defaultValue) const
-{
- return d->headerField(name, defaultValue);
-}
-
-void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data)
-{
- d->setHeaderField(name, data);
-}
-
-QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
-{
- d = other.d;
- return *this;
-}
-
-bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const
-{
- return d->operator==(*other.d);
-}
-
-QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const
-{
- return d->operation;
-}
-
-void QHttpNetworkRequest::setOperation(Operation operation)
-{
- d->operation = operation;
-}
-
-QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const
-{
- return d->priority;
-}
-
-void QHttpNetworkRequest::setPriority(Priority priority)
-{
- d->priority = priority;
-}
-
-QIODevice *QHttpNetworkRequest::data() const
-{
- return d->data;
-}
-
-void QHttpNetworkRequest::setData(QIODevice *data)
-{
- d->data = data;
-}
-
-int QHttpNetworkRequest::majorVersion() const
-{
- return 1;
-}
-
-int QHttpNetworkRequest::minorVersion() const
-{
- return 1;
-}
-
-// QHttpNetworkReply
-
-QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent)
- : QObject(*new QHttpNetworkReplyPrivate(url), parent)
-{
-}
-
-QHttpNetworkReply::~QHttpNetworkReply()
-{
- Q_D(QHttpNetworkReply);
- if (d->connection) {
- d->connection->d_func()->removeReply(this);
- }
-}
-
-QUrl QHttpNetworkReply::url() const
-{
- return d_func()->url;
-}
-void QHttpNetworkReply::setUrl(const QUrl &url)
-{
- Q_D(QHttpNetworkReply);
- d->url = url;
-}
-
-qint64 QHttpNetworkReply::contentLength() const
-{
- return d_func()->contentLength();
-}
-
-void QHttpNetworkReply::setContentLength(qint64 length)
-{
- Q_D(QHttpNetworkReply);
- d->setContentLength(length);
-}
-
-QList<QPair<QByteArray, QByteArray> > QHttpNetworkReply::header() const
-{
- return d_func()->fields;
-}
-
-QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const
-{
- return d_func()->headerField(name, defaultValue);
-}
-
-void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data)
-{
- Q_D(QHttpNetworkReply);
- d->setHeaderField(name, data);
-}
-
-void QHttpNetworkReply::parseHeader(const QByteArray &header)
-{
- Q_D(QHttpNetworkReply);
- d->parseHeader(header);
-}
-
-QHttpNetworkRequest QHttpNetworkReply::request() const
-{
- return d_func()->request;
-}
-
-void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request)
-{
- Q_D(QHttpNetworkReply);
- d->request = request;
-}
-
-int QHttpNetworkReply::statusCode() const
-{
- return d_func()->statusCode;
-}
-
-void QHttpNetworkReply::setStatusCode(int code)
-{
- Q_D(QHttpNetworkReply);
- d->statusCode = code;
-}
-
-QString QHttpNetworkReply::errorString() const
-{
- return d_func()->errorString;
-}
-
-QString QHttpNetworkReply::reasonPhrase() const
-{
- return d_func()->reasonPhrase;
-}
-
-void QHttpNetworkReply::setErrorString(const QString &error)
-{
- Q_D(QHttpNetworkReply);
- d->errorString = error;
-}
-
-int QHttpNetworkReply::majorVersion() const
-{
- return d_func()->majorVersion;
-}
-
-int QHttpNetworkReply::minorVersion() const
-{
- return d_func()->minorVersion;
-}
-
-qint64 QHttpNetworkReply::bytesAvailable() const
-{
- Q_D(const QHttpNetworkReply);
- if (d->connection)
- return d->connection->d_func()->bytesAvailable(*this);
- else
- return -1;
-}
-
-QByteArray QHttpNetworkReply::read(qint64 maxSize)
-{
- Q_D(QHttpNetworkReply);
- QByteArray data;
- if (d->connection)
- d->connection->d_func()->read(*this, data, maxSize, false);
- return data;
-}
-
-bool QHttpNetworkReply::isFinished() const
-{
- return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;
-}
// SSL support below
#ifndef QT_NO_OPENSSL
@@ -2433,27 +1338,7 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel)
}
}
-QSslConfiguration QHttpNetworkReply::sslConfiguration() const
-{
- Q_D(const QHttpNetworkReply);
- if (d->connection)
- return d->connection->d_func()->sslConfiguration(*this);
- return QSslConfiguration();
-}
-void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config)
-{
- Q_D(QHttpNetworkReply);
- if (d->connection)
- d->connection->setSslConfiguration(config);
-}
-
-void QHttpNetworkReply::ignoreSslErrors()
-{
- Q_D(QHttpNetworkReply);
- if (d->connection)
- d->connection->ignoreSslErrors();
-}
#endif //QT_NO_OPENSSL
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 8dbcb3d..09bd459 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -56,6 +56,16 @@
#include <QtNetwork/qnetworkreply.h>
#include <QtNetwork/qabstractsocket.h>
+#include <private/qobject_p.h>
+#include <qauthenticator.h>
+#include <qnetworkproxy.h>
+#include <qbuffer.h>
+
+#include <private/qhttpnetworkheader_p.h>
+#include <private/qhttpnetworkrequest_p.h>
+#include <private/qhttpnetworkreply_p.h>
+
+
#ifndef QT_NO_HTTP
#ifndef QT_NO_OPENSSL
@@ -145,144 +155,137 @@ private:
#endif
};
-class Q_AUTOTEST_EXPORT QHttpNetworkHeader
-{
-public:
- virtual ~QHttpNetworkHeader() {};
- virtual QUrl url() const = 0;
- virtual void setUrl(const QUrl &url) = 0;
- virtual int majorVersion() const = 0;
- virtual int minorVersion() const = 0;
- virtual qint64 contentLength() const = 0;
- virtual void setContentLength(qint64 length) = 0;
- virtual QList<QPair<QByteArray, QByteArray> > header() const = 0;
- virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0;
- virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0;
-};
+// private classes
+typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
+
-class QHttpNetworkRequestPrivate;
-class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader
+class QHttpNetworkConnectionPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QHttpNetworkConnection)
public:
- enum Operation {
- Options,
- Get,
- Head,
- Post,
- Put,
- Delete,
- Trace,
- Connect
+ QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
+ ~QHttpNetworkConnectionPrivate();
+ void init();
+ void connectSignals(QAbstractSocket *socket);
+
+ enum SocketState {
+ IdleState = 0, // ready to send request
+ ConnectingState = 1, // connecting to host
+ WritingState = 2, // writing the data
+ WaitingState = 4, // waiting for reply
+ ReadingState = 8, // reading the reply
+ Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done
+ BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState)
};
- enum Priority {
- HighPriority,
- NormalPriority,
- LowPriority
+ enum { ChunkSize = 4096 };
+
+ int indexOf(QAbstractSocket *socket) const;
+ bool isSocketBusy(QAbstractSocket *socket) const;
+ bool isSocketWriting(QAbstractSocket *socket) const;
+ bool isSocketWaiting(QAbstractSocket *socket) const;
+ bool isSocketReading(QAbstractSocket *socket) const;
+
+ QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
+ void unqueueRequest(QAbstractSocket *socket);
+ void prepareRequest(HttpMessagePair &request);
+ bool sendRequest(QAbstractSocket *socket);
+ void receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply);
+ void resendCurrentRequest(QAbstractSocket *socket);
+ void closeChannel(int channel);
+ void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
+
+ // private slots
+ void _q_bytesWritten(qint64 bytes); // proceed sending
+ void _q_readyRead(); // pending data to read
+ void _q_disconnected(); // disconnected from host
+ void _q_startNextRequest(); // send the next request from the queue
+ void _q_restartPendingRequest(); // send the currently blocked request
+ void _q_connected(); // start sending request
+ void _q_error(QAbstractSocket::SocketError); // error from socket
+#ifndef QT_NO_NETWORKPROXY
+ void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
+#endif
+ void _q_dataReadyReadNoBuffer();
+ void _q_dataReadyReadBuffer();
+
+ void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
+ bool ensureConnection(QAbstractSocket *socket);
+ QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket);
+ void eraseData(QHttpNetworkReply *reply);
+#ifndef QT_NO_COMPRESS
+ bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete);
+#endif
+ void bufferData(HttpMessagePair &request);
+ void removeReply(QHttpNetworkReply *reply);
+
+ QString hostName;
+ quint16 port;
+ bool encrypt;
+
+ struct Channel {
+ QAbstractSocket *socket;
+ SocketState state;
+ QHttpNetworkRequest request; // current request
+ QHttpNetworkReply *reply; // current reply for this request
+ qint64 written;
+ qint64 bytesTotal;
+ bool resendCurrent;
+ int lastStatus; // last status received on this channel
+ bool pendingEncrypt; // for https (send after encrypted)
+ int reconnectAttempts; // maximum 2 reconnection attempts
+ QAuthenticatorPrivate::Method authMehtod;
+ QAuthenticatorPrivate::Method proxyAuthMehtod;
+ QAuthenticator authenticator;
+ QAuthenticator proxyAuthenticator;
+#ifndef QT_NO_OPENSSL
+ bool ignoreSSLErrors;
+#endif
+ Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2),
+ authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None)
+#ifndef QT_NO_OPENSSL
+ , ignoreSSLErrors(false)
+#endif
+ {}
};
-
- QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority);
- QHttpNetworkRequest(const QHttpNetworkRequest &other);
- virtual ~QHttpNetworkRequest();
- QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other);
- bool operator==(const QHttpNetworkRequest &other) const;
-
- QUrl url() const;
- void setUrl(const QUrl &url);
-
- int majorVersion() const;
- int minorVersion() const;
-
- qint64 contentLength() const;
- void setContentLength(qint64 length);
-
- QList<QPair<QByteArray, QByteArray> > header() const;
- QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
- void setHeaderField(const QByteArray &name, const QByteArray &data);
-
- Operation operation() const;
- void setOperation(Operation operation);
-
- Priority priority() const;
- void setPriority(Priority priority);
-
- QIODevice *data() const;
- void setData(QIODevice *data);
-
-private:
- QSharedDataPointer<QHttpNetworkRequestPrivate> d;
- friend class QHttpNetworkRequestPrivate;
- friend class QHttpNetworkConnectionPrivate;
-};
-
-class QHttpNetworkReplyPrivate;
-class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader
-{
- Q_OBJECT
-public:
-
- explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0);
- virtual ~QHttpNetworkReply();
-
- QUrl url() const;
- void setUrl(const QUrl &url);
-
- int majorVersion() const;
- int minorVersion() const;
-
- qint64 contentLength() const;
- void setContentLength(qint64 length);
-
- QList<QPair<QByteArray, QByteArray> > header() const;
- QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
- void setHeaderField(const QByteArray &name, const QByteArray &data);
- void parseHeader(const QByteArray &header); // mainly for testing
-
- QHttpNetworkRequest request() const;
- void setRequest(const QHttpNetworkRequest &request);
-
- int statusCode() const;
- void setStatusCode(int code);
-
- QString errorString() const;
- void setErrorString(const QString &error);
-
- QString reasonPhrase() const;
-
- qint64 bytesAvailable() const;
- QByteArray read(qint64 maxSize = -1);
-
- bool isFinished() const;
+ static const int channelCount;
+ Channel channels[2]; // maximum of 2 socket connections to the server
+ bool pendingAuthSignal; // there is an incomplete authentication signal
+ bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal
+
+ void appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed);
+ qint64 bytesAvailable(const QHttpNetworkReply &reply, bool compressed = false) const;
+ qint64 read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed);
+ void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
+ bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
+ void allDone(QAbstractSocket *socket, QHttpNetworkReply *reply);
+ void handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply);
+ inline bool emitSignals(QHttpNetworkReply *reply);
+ inline bool expectContent(QHttpNetworkReply *reply);
#ifndef QT_NO_OPENSSL
- QSslConfiguration sslConfiguration() const;
- void setSslConfiguration(const QSslConfiguration &config);
- void ignoreSslErrors();
-
-Q_SIGNALS:
- void sslErrors(const QList<QSslError> &errors);
+ void _q_encrypted(); // start sending request (https)
+ void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
+ QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const;
#endif
-Q_SIGNALS:
- void readyRead();
- void finished();
- void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
- void headerChanged();
- void dataReadProgress(int done, int total);
- void dataSendProgress(int done, int total);
+#ifndef QT_NO_NETWORKPROXY
+ QNetworkProxy networkProxy;
+#endif
-private:
- Q_DECLARE_PRIVATE(QHttpNetworkReply)
- friend class QHttpNetworkConnection;
- friend class QHttpNetworkConnectionPrivate;
+ //The request queues
+ QList<HttpMessagePair> highPriorityQueue;
+ QList<HttpMessagePair> lowPriorityQueue;
};
+
+
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QHttpNetworkRequest)
+//Q_DECLARE_METATYPE(QHttpNetworkRequest)
//Q_DECLARE_METATYPE(QHttpNetworkReply)
#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp
new file mode 100644
index 0000000..6f7f6f7
--- /dev/null
+++ b/src/network/access/qhttpnetworkheader.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhttpnetworkheader_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl)
+ :url(newUrl)
+{
+}
+
+QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other)
+ :QSharedData(other)
+{
+ url = other.url;
+ fields = other.fields;
+}
+
+qint64 QHttpNetworkHeaderPrivate::contentLength() const
+{
+ bool ok = false;
+ QByteArray value = headerField("content-length");
+ qint64 length = value.toULongLong(&ok);
+ if (ok)
+ return length;
+ return -1; // the header field is not set
+}
+
+void QHttpNetworkHeaderPrivate::setContentLength(qint64 length)
+{
+ setHeaderField("Content-Length", QByteArray::number(length));
+}
+
+QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray &defaultValue) const
+{
+ QList<QByteArray> allValues = headerFieldValues(name);
+ if (allValues.isEmpty())
+ return defaultValue;
+
+ QByteArray result;
+ bool first = true;
+ foreach (QByteArray value, allValues) {
+ if (!first)
+ result += ", ";
+ first = false;
+ result += value;
+ }
+ return result;
+}
+
+QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const
+{
+ QList<QByteArray> result;
+ QByteArray lowerName = name.toLower();
+ QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
+ end = fields.constEnd();
+ for ( ; it != end; ++it)
+ if (lowerName == it->first.toLower())
+ result += it->second;
+
+ return result;
+}
+
+void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ QByteArray lowerName = name.toLower();
+ QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin();
+ while (it != fields.end()) {
+ if (lowerName == it->first.toLower())
+ it = fields.erase(it);
+ else
+ ++it;
+ }
+ fields.append(qMakePair(name, data));
+}
+
+bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const
+{
+ return (url == other.url);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h
new file mode 100644
index 0000000..4e62352
--- /dev/null
+++ b/src/network/access/qhttpnetworkheader_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTPNETWORKHEADER_H
+#define QHTTPNETWORKHEADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+#ifndef QT_NO_HTTP
+
+#include <qshareddata.h>
+#include <qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QHttpNetworkHeader
+{
+public:
+ virtual ~QHttpNetworkHeader() {};
+ virtual QUrl url() const = 0;
+ virtual void setUrl(const QUrl &url) = 0;
+
+ virtual int majorVersion() const = 0;
+ virtual int minorVersion() const = 0;
+
+ virtual qint64 contentLength() const = 0;
+ virtual void setContentLength(qint64 length) = 0;
+
+ virtual QList<QPair<QByteArray, QByteArray> > header() const = 0;
+ virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0;
+ virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0;
+};
+
+class QHttpNetworkHeaderPrivate : public QSharedData
+{
+public:
+ QUrl url;
+ QList<QPair<QByteArray, QByteArray> > fields;
+
+ QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl());
+ QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other);
+ qint64 contentLength() const;
+ void setContentLength(qint64 length);
+
+ QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
+ QList<QByteArray> headerFieldValues(const QByteArray &name) const;
+ void setHeaderField(const QByteArray &name, const QByteArray &data);
+ bool operator==(const QHttpNetworkHeaderPrivate &other) const;
+
+};
+
+
+QT_END_NAMESPACE
+
+
+#endif // QT_NO_HTTP
+
+
+#endif // QHTTPNETWORKHEADER_H
+
+
+
+
+
+
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
new file mode 100644
index 0000000..fe3f6af
--- /dev/null
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -0,0 +1,663 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhttpnetworkreply_p.h"
+#include "qhttpnetworkconnection_p.h"
+
+#include <qbytearraymatcher.h>
+
+#ifndef QT_NO_HTTP
+
+#ifndef QT_NO_OPENSSL
+# include <QtNetwork/qsslkey.h>
+# include <QtNetwork/qsslcipher.h>
+# include <QtNetwork/qsslconfiguration.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent)
+ : QObject(*new QHttpNetworkReplyPrivate(url), parent)
+{
+}
+
+QHttpNetworkReply::~QHttpNetworkReply()
+{
+ Q_D(QHttpNetworkReply);
+ if (d->connection) {
+ d->connection->d_func()->removeReply(this);
+ }
+}
+
+QUrl QHttpNetworkReply::url() const
+{
+ return d_func()->url;
+}
+void QHttpNetworkReply::setUrl(const QUrl &url)
+{
+ Q_D(QHttpNetworkReply);
+ d->url = url;
+}
+
+qint64 QHttpNetworkReply::contentLength() const
+{
+ return d_func()->contentLength();
+}
+
+void QHttpNetworkReply::setContentLength(qint64 length)
+{
+ Q_D(QHttpNetworkReply);
+ d->setContentLength(length);
+}
+
+QList<QPair<QByteArray, QByteArray> > QHttpNetworkReply::header() const
+{
+ return d_func()->fields;
+}
+
+QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const
+{
+ return d_func()->headerField(name, defaultValue);
+}
+
+void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ Q_D(QHttpNetworkReply);
+ d->setHeaderField(name, data);
+}
+
+void QHttpNetworkReply::parseHeader(const QByteArray &header)
+{
+ Q_D(QHttpNetworkReply);
+ d->parseHeader(header);
+}
+
+QHttpNetworkRequest QHttpNetworkReply::request() const
+{
+ return d_func()->request;
+}
+
+void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request)
+{
+ Q_D(QHttpNetworkReply);
+ d->request = request;
+}
+
+int QHttpNetworkReply::statusCode() const
+{
+ return d_func()->statusCode;
+}
+
+void QHttpNetworkReply::setStatusCode(int code)
+{
+ Q_D(QHttpNetworkReply);
+ d->statusCode = code;
+}
+
+QString QHttpNetworkReply::errorString() const
+{
+ return d_func()->errorString;
+}
+
+QString QHttpNetworkReply::reasonPhrase() const
+{
+ return d_func()->reasonPhrase;
+}
+
+void QHttpNetworkReply::setErrorString(const QString &error)
+{
+ Q_D(QHttpNetworkReply);
+ d->errorString = error;
+}
+
+int QHttpNetworkReply::majorVersion() const
+{
+ return d_func()->majorVersion;
+}
+
+int QHttpNetworkReply::minorVersion() const
+{
+ return d_func()->minorVersion;
+}
+
+qint64 QHttpNetworkReply::bytesAvailable() const
+{
+ Q_D(const QHttpNetworkReply);
+ if (d->connection)
+ return d->connection->d_func()->bytesAvailable(*this);
+ else
+ return -1;
+}
+
+QByteArray QHttpNetworkReply::read(qint64 maxSize)
+{
+ Q_D(QHttpNetworkReply);
+ QByteArray data;
+ if (d->connection)
+ d->connection->d_func()->read(*this, data, maxSize, false);
+ return data;
+}
+
+bool QHttpNetworkReply::isFinished() const
+{
+ return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;
+}
+
+
+
+QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
+ : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
+ majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
+ currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
+ autoDecompress(false), requestIsBuffering(false), requestIsPrepared(false)
+{
+}
+
+QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
+{
+}
+
+void QHttpNetworkReplyPrivate::clear()
+{
+ state = NothingDoneState;
+ statusCode = 100;
+ bodyLength = 0;
+ contentRead = 0;
+ totalProgress = 0;
+ currentChunkSize = 0;
+ currentChunkRead = 0;
+ connection = 0;
+#ifndef QT_NO_COMPRESS
+ if (initInflate)
+ inflateEnd(&inflateStrm);
+#endif
+ initInflate = false;
+ streamEnd = false;
+ autoDecompress = false;
+ fields.clear();
+}
+
+// QHttpNetworkReplyPrivate
+qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
+{
+ return (state != ReadingDataState ? 0 : fragment.size());
+}
+
+bool QHttpNetworkReplyPrivate::isGzipped()
+{
+ QByteArray encoding = headerField("content-encoding");
+ return encoding.toLower() == "gzip";
+}
+
+void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
+{
+ // The header "Content-Encoding = gzip" is retained.
+ // Content-Length is removed since the actual one send by the server is for compressed data
+ QByteArray name("content-length");
+ QByteArray lowerName = name.toLower();
+ QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
+ end = fields.end();
+ while (it != end) {
+ if (name == it->first.toLower()) {
+ fields.erase(it);
+ break;
+ }
+ ++it;
+ }
+
+}
+
+bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const
+{
+ challenge.clear();
+ // find out the type of authentication protocol requested.
+ QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate";
+ // pick the best protocol (has to match parsing in QAuthenticatorPrivate)
+ QList<QByteArray> challenges = headerFieldValues(header);
+ for (int i = 0; i<challenges.size(); i++) {
+ QByteArray line = challenges.at(i);
+ if (!line.toLower().startsWith("negotiate"))
+ challenge = line;
+ }
+ return !challenge.isEmpty();
+}
+
+QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(bool isProxy) const
+{
+ // The logic is same as the one used in void QAuthenticatorPrivate::parseHttpResponse()
+ QAuthenticatorPrivate::Method method = QAuthenticatorPrivate::None;
+ QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
+ QList<QByteArray> challenges = headerFieldValues(header);
+ for (int i = 0; i<challenges.size(); i++) {
+ QByteArray line = challenges.at(i).trimmed().toLower();
+ if (method < QAuthenticatorPrivate::Basic
+ && line.startsWith("basic")) {
+ method = QAuthenticatorPrivate::Basic;
+ } else if (method < QAuthenticatorPrivate::Ntlm
+ && line.startsWith("ntlm")) {
+ method = QAuthenticatorPrivate::Ntlm;
+ } else if (method < QAuthenticatorPrivate::DigestMd5
+ && line.startsWith("digest")) {
+ method = QAuthenticatorPrivate::DigestMd5;
+ }
+ }
+ return method;
+}
+
+#ifndef QT_NO_COMPRESS
+bool QHttpNetworkReplyPrivate::gzipCheckHeader(QByteArray &content, int &pos)
+{
+ int method = 0; // method byte
+ int flags = 0; // flags byte
+ bool ret = false;
+
+ // Assure two bytes in the buffer so we can peek ahead -- handle case
+ // where first byte of header is at the end of the buffer after the last
+ // gzip segment
+ pos = -1;
+ QByteArray &body = content;
+ int maxPos = body.size()-1;
+ if (maxPos < 1) {
+ return ret;
+ }
+
+ // Peek ahead to check the gzip magic header
+ if (body[0] != char(gz_magic[0]) ||
+ body[1] != char(gz_magic[1])) {
+ return ret;
+ }
+ pos += 2;
+ // Check the rest of the gzip header
+ if (++pos <= maxPos)
+ method = body[pos];
+ if (pos++ <= maxPos)
+ flags = body[pos];
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ return ret;
+ }
+
+ // Discard time, xflags and OS code:
+ pos += 6;
+ if (pos > maxPos)
+ return ret;
+ if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field
+ unsigned len = (unsigned)body[++pos];
+ len += ((unsigned)body[++pos])<<8;
+ pos += len;
+ if (pos > maxPos)
+ return ret;
+ }
+ if ((flags & ORIG_NAME) != 0) { // skip the original file name
+ while(++pos <= maxPos && body[pos]) {}
+ }
+ if ((flags & COMMENT) != 0) { // skip the .gz file comment
+ while(++pos <= maxPos && body[pos]) {}
+ }
+ if ((flags & HEAD_CRC) != 0) { // skip the header crc
+ pos += 2;
+ if (pos > maxPos)
+ return ret;
+ }
+ ret = (pos < maxPos); // return failed, if no more bytes left
+ return ret;
+}
+
+int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated)
+{
+ int ret = Z_DATA_ERROR;
+ unsigned have;
+ unsigned char out[CHUNK];
+ int pos = -1;
+
+ if (!initInflate) {
+ // check the header
+ if (!gzipCheckHeader(compressed, pos))
+ return ret;
+ // allocate inflate state
+ inflateStrm.zalloc = Z_NULL;
+ inflateStrm.zfree = Z_NULL;
+ inflateStrm.opaque = Z_NULL;
+ inflateStrm.avail_in = 0;
+ inflateStrm.next_in = Z_NULL;
+ ret = inflateInit2(&inflateStrm, -MAX_WBITS);
+ if (ret != Z_OK)
+ return ret;
+ initInflate = true;
+ streamEnd = false;
+ }
+
+ //remove the header.
+ compressed.remove(0, pos+1);
+ // expand until deflate stream ends
+ inflateStrm.next_in = (unsigned char *)compressed.data();
+ inflateStrm.avail_in = compressed.size();
+ do {
+ inflateStrm.avail_out = sizeof(out);
+ inflateStrm.next_out = out;
+ ret = inflate(&inflateStrm, Z_NO_FLUSH);
+ switch (ret) {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ // and fall through
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&inflateStrm);
+ initInflate = false;
+ return ret;
+ }
+ have = sizeof(out) - inflateStrm.avail_out;
+ inflated.append(QByteArray((const char *)out, have));
+ } while (inflateStrm.avail_out == 0);
+ // clean up and return
+ if (ret <= Z_ERRNO || ret == Z_STREAM_END) {
+ inflateEnd(&inflateStrm);
+ initInflate = false;
+ }
+ streamEnd = (ret == Z_STREAM_END);
+ return ret;
+}
+#endif
+
+qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
+{
+ qint64 bytes = 0;
+ char c;
+
+ while (socket->bytesAvailable()) {
+ // allow both CRLF & LF (only) line endings
+ if (socket->peek(&c, 1) == 1 && c == '\n') {
+ bytes += socket->read(&c, 1); // read the "n"
+ // remove the CR at the end
+ if (fragment.endsWith('\r')) {
+ fragment.truncate(fragment.length()-1);
+ }
+ parseStatus(fragment);
+ state = ReadingHeaderState;
+ fragment.clear(); // next fragment
+ break;
+ } else {
+ c = 0;
+ bytes += socket->read(&c, 1);
+ fragment.append(c);
+ }
+ }
+ return bytes;
+}
+
+void QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status)
+{
+ const QByteArrayMatcher sp(" ");
+ int i = sp.indexIn(status);
+ const QByteArray version = status.mid(0, i);
+ int j = sp.indexIn(status, i + 1);
+ const QByteArray code = status.mid(i + 1, j - i - 1);
+ const QByteArray reason = status.mid(j + 1, status.count() - j);
+
+ const QByteArrayMatcher slash("/");
+ int k = slash.indexIn(version);
+ const QByteArrayMatcher dot(".");
+ int l = dot.indexIn(version, k);
+ const QByteArray major = version.mid(k + 1, l - k - 1);
+ const QByteArray minor = version.mid(l + 1, version.count() - l);
+
+ majorVersion = QString::fromAscii(major.constData()).toInt();
+ minorVersion = QString::fromAscii(minor.constData()).toInt();
+ statusCode = QString::fromAscii(code.constData()).toInt();
+ reasonPhrase = QString::fromAscii(reason.constData());
+}
+
+qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
+{
+ qint64 bytes = 0;
+ char crlfcrlf[5];
+ crlfcrlf[4] = '\0';
+ char c = 0;
+ bool allHeaders = false;
+ while (!allHeaders && socket->bytesAvailable()) {
+ if (socket->peek(&c, 1) == 1 && c == '\n') {
+ // check for possible header endings. As per HTTP rfc,
+ // the header endings will be marked by CRLFCRLF. But
+ // we will allow CRLFLF, LFLF & CRLFCRLF
+ if (fragment.endsWith("\n\r") || fragment.endsWith('\n'))
+ allHeaders = true;
+ }
+ bytes += socket->read(&c, 1);
+ fragment.append(c);
+ }
+ // we received all headers now parse them
+ if (allHeaders) {
+ parseHeader(fragment);
+ state = ReadingDataState;
+ fragment.clear(); // next fragment
+ bodyLength = contentLength(); // cache the length
+ }
+ return bytes;
+}
+
+void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header)
+{
+ // see rfc2616, sec 4 for information about HTTP/1.1 headers.
+ // allows relaxed parsing here, accepts both CRLF & LF line endings
+ const QByteArrayMatcher lf("\n");
+ const QByteArrayMatcher colon(":");
+ int i = 0;
+ while (i < header.count()) {
+ int j = colon.indexIn(header, i); // field-name
+ if (j == -1)
+ break;
+ const QByteArray field = header.mid(i, j - i).trimmed();
+ j++;
+ // any number of LWS is allowed before and after the value
+ QByteArray value;
+ do {
+ i = lf.indexIn(header, j);
+ if (i == -1)
+ break;
+ if (!value.isEmpty())
+ value += ' ';
+ // check if we have CRLF or only LF
+ bool hasCR = (i && header[i-1] == '\r');
+ int length = i -(hasCR ? 1: 0) - j;
+ value += header.mid(j, length).trimmed();
+ j = ++i;
+ } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t'));
+ if (i == -1)
+ break; // something is wrong
+
+ fields.append(qMakePair(field, value));
+ }
+}
+
+bool QHttpNetworkReplyPrivate::isChunked()
+{
+ return headerField("transfer-encoding").toLower().contains("chunked");
+}
+
+bool QHttpNetworkReplyPrivate::connectionCloseEnabled()
+{
+ return (headerField("connection").toLower().contains("close") ||
+ headerField("proxy-connection").toLower().contains("close"));
+}
+
+qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QIODevice *out)
+{
+ qint64 bytes = 0;
+ if (isChunked()) {
+ bytes += transferChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6)
+ } else if (bodyLength > 0) { // we have a Content-Length
+ bytes += transferRaw(socket, out, bodyLength - contentRead);
+ if (contentRead + bytes == bodyLength)
+ state = AllDoneState;
+ } else {
+ bytes += transferRaw(socket, out, socket->bytesAvailable());
+ }
+ if (state == AllDoneState)
+ socket->readAll(); // Read the rest to clean (CRLF)
+ contentRead += bytes;
+ return bytes;
+}
+
+qint64 QHttpNetworkReplyPrivate::transferRaw(QIODevice *in, QIODevice *out, qint64 size)
+{
+ qint64 bytes = 0;
+ Q_ASSERT(in);
+ Q_ASSERT(out);
+
+ int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, in->bytesAvailable()));
+ QByteArray raw(toBeRead, 0);
+ while (size > 0) {
+ qint64 read = in->read(raw.data(), raw.size());
+ if (read == 0)
+ return bytes;
+ // ### error checking here
+ qint64 written = out->write(raw.data(), read);
+ if (written == 0)
+ return bytes;
+ if (read != written)
+ qDebug() << "### read" << read << "written" << written;
+ bytes += read;
+ size -= read;
+ out->waitForBytesWritten(-1); // throttle
+ }
+ return bytes;
+
+}
+
+qint64 QHttpNetworkReplyPrivate::transferChunked(QIODevice *in, QIODevice *out)
+{
+ qint64 bytes = 0;
+ while (in->bytesAvailable()) { // while we can read from input
+ // if we are done with the current chunk, get the size of the new chunk
+ if (currentChunkRead >= currentChunkSize) {
+ currentChunkSize = 0;
+ currentChunkRead = 0;
+ if (bytes) {
+ char crlf[2];
+ bytes += in->read(crlf, 2); // read the "\r\n" after the chunk
+ }
+ bytes += getChunkSize(in, &currentChunkSize);
+ if (currentChunkSize == -1)
+ break;
+ }
+ // if the chunk size is 0, end of the stream
+ if (currentChunkSize == 0) {
+ state = AllDoneState;
+ break;
+ }
+ // otherwise, read data
+ qint64 readSize = qMin(in->bytesAvailable(), currentChunkSize - currentChunkRead);
+ QByteArray buffer(readSize, 0);
+ qint64 read = in->read(buffer.data(), readSize);
+ bytes += read;
+ currentChunkRead += read;
+ qint64 written = out->write(buffer);
+ Q_UNUSED(written); // Avoid compile warning when building release
+ Q_ASSERT(read == written);
+ // ### error checking here
+ out->waitForBytesWritten(-1);
+ }
+ return bytes;
+}
+
+qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize)
+{
+ qint64 bytes = 0;
+ char crlf[2];
+ *chunkSize = -1;
+ int bytesAvailable = in->bytesAvailable();
+ while (bytesAvailable > bytes) {
+ qint64 sniffedBytes = in->peek(crlf, 2);
+ int fragmentSize = fragment.size();
+ // check the next two bytes for a "\r\n", skip blank lines
+ if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n')
+ ||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n'))
+ {
+ bytes += in->read(crlf, 1); // read the \r or \n
+ if (crlf[0] == '\r')
+ bytes += in->read(crlf, 1); // read the \n
+ bool ok = false;
+ // ignore the chunk-extension
+ fragment = fragment.mid(0, fragment.indexOf(';')).trimmed();
+ *chunkSize = fragment.toLong(&ok, 16);
+ fragment.clear();
+ break; // size done
+ } else {
+ // read the fragment to the buffer
+ char c = 0;
+ bytes += in->read(&c, 1);
+ fragment.append(c);
+ }
+ }
+ return bytes;
+}
+
+// SSL support below
+#ifndef QT_NO_OPENSSL
+
+QSslConfiguration QHttpNetworkReply::sslConfiguration() const
+{
+ Q_D(const QHttpNetworkReply);
+ if (d->connection)
+ return d->connection->d_func()->sslConfiguration(*this);
+ return QSslConfiguration();
+}
+
+void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config)
+{
+ Q_D(QHttpNetworkReply);
+ if (d->connection)
+ d->connection->setSslConfiguration(config);
+}
+
+void QHttpNetworkReply::ignoreSslErrors()
+{
+ Q_D(QHttpNetworkReply);
+ if (d->connection)
+ d->connection->ignoreSslErrors();
+}
+
+
+#endif //QT_NO_OPENSSL
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_HTTP \ No newline at end of file
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
new file mode 100644
index 0000000..c17c65c
--- /dev/null
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTPNETWORKREPLY_H
+#define QHTTPNETWORKREPLY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+#ifndef QT_NO_HTTP
+
+#ifndef QT_NO_COMPRESS
+# include <zlib.h>
+static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header
+// gzip flag byte
+#define HEAD_CRC 0x02 // bit 1 set: header CRC present
+#define EXTRA_FIELD 0x04 // bit 2 set: extra field present
+#define ORIG_NAME 0x08 // bit 3 set: original file name present
+#define COMMENT 0x10 // bit 4 set: file comment present
+#define RESERVED 0xE0 // bits 5..7: reserved
+#define CHUNK 16384
+#endif
+
+#include <QtNetwork/qtcpsocket.h>
+// it's safe to include these even if SSL support is not enabled
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qsslerror.h>
+
+#include <QtNetwork/qnetworkrequest.h>
+#include <QtNetwork/qnetworkreply.h>
+#include <qbuffer.h>
+
+#include <private/qobject_p.h>
+#include <private/qhttpnetworkheader_p.h>
+#include <private/qhttpnetworkrequest_p.h>
+#include <private/qauthenticator_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHttpNetworkConnection;
+class QHttpNetworkRequest;
+class QHttpNetworkConnectionPrivate;
+class QHttpNetworkReplyPrivate;
+class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader
+{
+ Q_OBJECT
+public:
+
+ explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0);
+ virtual ~QHttpNetworkReply();
+
+ QUrl url() const;
+ void setUrl(const QUrl &url);
+
+ int majorVersion() const;
+ int minorVersion() const;
+
+ qint64 contentLength() const;
+ void setContentLength(qint64 length);
+
+ QList<QPair<QByteArray, QByteArray> > header() const;
+ QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
+ void setHeaderField(const QByteArray &name, const QByteArray &data);
+ void parseHeader(const QByteArray &header); // mainly for testing
+
+ QHttpNetworkRequest request() const;
+ void setRequest(const QHttpNetworkRequest &request);
+
+ int statusCode() const;
+ void setStatusCode(int code);
+
+ QString errorString() const;
+ void setErrorString(const QString &error);
+
+ QString reasonPhrase() const;
+
+ qint64 bytesAvailable() const;
+ QByteArray read(qint64 maxSize = -1);
+
+ bool isFinished() const;
+
+#ifndef QT_NO_OPENSSL
+ QSslConfiguration sslConfiguration() const;
+ void setSslConfiguration(const QSslConfiguration &config);
+ void ignoreSslErrors();
+
+Q_SIGNALS:
+ void sslErrors(const QList<QSslError> &errors);
+#endif
+
+Q_SIGNALS:
+ void readyRead();
+ void finished();
+ void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
+ void headerChanged();
+ void dataReadProgress(int done, int total);
+ void dataSendProgress(int done, int total);
+
+private:
+ Q_DECLARE_PRIVATE(QHttpNetworkReply)
+ friend class QHttpNetworkConnection;
+ friend class QHttpNetworkConnectionPrivate;
+};
+
+
+class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
+{
+public:
+ QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl());
+ ~QHttpNetworkReplyPrivate();
+ qint64 readStatus(QAbstractSocket *socket);
+ void parseStatus(const QByteArray &status);
+ qint64 readHeader(QAbstractSocket *socket);
+ void parseHeader(const QByteArray &header);
+ qint64 readBody(QAbstractSocket *socket, QIODevice *out);
+ bool findChallenge(bool forProxy, QByteArray &challenge) const;
+ QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
+ void clear();
+
+ qint64 transferRaw(QIODevice *in, QIODevice *out, qint64 size);
+ qint64 transferChunked(QIODevice *in, QIODevice *out);
+ qint64 getChunkSize(QIODevice *in, qint64 *chunkSize);
+
+ qint64 bytesAvailable() const;
+ bool isChunked();
+ bool connectionCloseEnabled();
+ bool isGzipped();
+#ifndef QT_NO_COMPRESS
+ bool gzipCheckHeader(QByteArray &content, int &pos);
+ int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated);
+#endif
+ void removeAutoDecompressHeader();
+
+ enum ReplyState {
+ NothingDoneState,
+ ReadingStatusState,
+ ReadingHeaderState,
+ ReadingDataState,
+ AllDoneState
+ } state;
+
+ QHttpNetworkRequest request;
+ int statusCode;
+ int majorVersion;
+ int minorVersion;
+ QString errorString;
+ QString reasonPhrase;
+ qint64 bodyLength;
+ qint64 contentRead;
+ qint64 totalProgress;
+ QByteArray fragment;
+ qint64 currentChunkSize;
+ qint64 currentChunkRead;
+ QPointer<QHttpNetworkConnection> connection;
+ bool initInflate;
+ bool streamEnd;
+#ifndef QT_NO_COMPRESS
+ z_stream inflateStrm;
+#endif
+ bool autoDecompress;
+
+ QByteArray responseData; // uncompressed body
+ QByteArray compressedData; // compressed body (temporary)
+ QBuffer requestDataBuffer;
+ bool requestIsBuffering;
+ bool requestIsPrepared;
+};
+
+
+
+
+QT_END_NAMESPACE
+
+//Q_DECLARE_METATYPE(QHttpNetworkReply)
+
+#endif // QT_NO_HTTP
+
+
+#endif // QHTTPNETWORKREPLY_H
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
new file mode 100644
index 0000000..420cb69
--- /dev/null
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhttpnetworkrequest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
+ QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
+ : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), data(0),
+ autoDecompress(false)
+{
+}
+
+QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other)
+ : QHttpNetworkHeaderPrivate(other)
+{
+ operation = other.operation;
+ priority = other.priority;
+ data = other.data;
+ autoDecompress = other.autoDecompress;
+}
+
+QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
+{
+}
+
+bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const
+{
+ return QHttpNetworkHeaderPrivate::operator==(other)
+ && (operation == other.operation)
+ && (data == other.data);
+}
+
+QByteArray QHttpNetworkRequestPrivate::methodName() const
+{
+ QByteArray ba;
+ switch (operation) {
+ case QHttpNetworkRequest::Options:
+ ba += "OPTIONS";
+ break;
+ case QHttpNetworkRequest::Get:
+ ba += "GET";
+ break;
+ case QHttpNetworkRequest::Head:
+ ba += "HEAD";
+ break;
+ case QHttpNetworkRequest::Post:
+ ba += "POST";
+ break;
+ case QHttpNetworkRequest::Put:
+ ba += "PUT";
+ break;
+ case QHttpNetworkRequest::Delete:
+ ba += "DELETE";
+ break;
+ case QHttpNetworkRequest::Trace:
+ ba += "TRACE";
+ break;
+ case QHttpNetworkRequest::Connect:
+ ba += "CONNECT";
+ break;
+ default:
+ break;
+ }
+ return ba;
+}
+
+QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const
+{
+ QUrl::FormattingOptions format(QUrl::RemoveFragment);
+
+ // for POST, query data is send as content
+ if (operation == QHttpNetworkRequest::Post && !data)
+ format |= QUrl::RemoveQuery;
+ // for requests through proxy, the Request-URI contains full url
+ if (throughProxy)
+ format |= QUrl::RemoveUserInfo;
+ else
+ format |= QUrl::RemoveScheme | QUrl::RemoveAuthority;
+ QByteArray uri = url.toEncoded(format);
+ if (uri.isEmpty() || (throughProxy && url.path().isEmpty()))
+ uri += '/';
+ return uri;
+}
+
+QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy)
+{
+ QByteArray ba = request.d->methodName();
+ QByteArray uri = request.d->uri(throughProxy);
+ ba += " " + uri;
+
+ QString majorVersion = QString::number(request.majorVersion());
+ QString minorVersion = QString::number(request.minorVersion());
+ ba += " HTTP/" + majorVersion.toLatin1() + "." + minorVersion.toLatin1() + "\r\n";
+
+ QList<QPair<QByteArray, QByteArray> > fields = request.header();
+ QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin();
+ for (; it != fields.constEnd(); ++it)
+ ba += it->first + ": " + it->second + "\r\n";
+ if (request.d->operation == QHttpNetworkRequest::Post) {
+ // add content type, if not set in the request
+ if (request.headerField("content-type").isEmpty())
+ ba += "Content-Type: application/x-www-form-urlencoded\r\n";
+ if (!request.d->data && request.d->url.hasQuery()) {
+ QByteArray query = request.d->url.encodedQuery();
+ ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n";
+ ba += "\r\n";
+ ba += query;
+ } else {
+ ba += "\r\n";
+ }
+ } else {
+ ba += "\r\n";
+ }
+ return ba;
+}
+
+
+// QHttpNetworkRequest
+
+QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority)
+ : d(new QHttpNetworkRequestPrivate(operation, priority, url))
+{
+}
+
+QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other)
+ : QHttpNetworkHeader(other), d(other.d)
+{
+}
+
+QHttpNetworkRequest::~QHttpNetworkRequest()
+{
+}
+
+QUrl QHttpNetworkRequest::url() const
+{
+ return d->url;
+}
+void QHttpNetworkRequest::setUrl(const QUrl &url)
+{
+ d->url = url;
+}
+
+qint64 QHttpNetworkRequest::contentLength() const
+{
+ return d->contentLength();
+}
+
+void QHttpNetworkRequest::setContentLength(qint64 length)
+{
+ d->setContentLength(length);
+}
+
+QList<QPair<QByteArray, QByteArray> > QHttpNetworkRequest::header() const
+{
+ return d->fields;
+}
+
+QByteArray QHttpNetworkRequest::headerField(const QByteArray &name, const QByteArray &defaultValue) const
+{
+ return d->headerField(name, defaultValue);
+}
+
+void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ d->setHeaderField(name, data);
+}
+
+QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
+{
+ d = other.d;
+ return *this;
+}
+
+bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const
+{
+ return d->operator==(*other.d);
+}
+
+QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const
+{
+ return d->operation;
+}
+
+void QHttpNetworkRequest::setOperation(Operation operation)
+{
+ d->operation = operation;
+}
+
+QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const
+{
+ return d->priority;
+}
+
+void QHttpNetworkRequest::setPriority(Priority priority)
+{
+ d->priority = priority;
+}
+
+QIODevice *QHttpNetworkRequest::data() const
+{
+ return d->data;
+}
+
+void QHttpNetworkRequest::setData(QIODevice *data)
+{
+ d->data = data;
+}
+
+int QHttpNetworkRequest::majorVersion() const
+{
+ return 1;
+}
+
+int QHttpNetworkRequest::minorVersion() const
+{
+ return 1;
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
new file mode 100644
index 0000000..d18e116
--- /dev/null
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTPNETWORKREQUEST_H
+#define QHTTPNETWORKREQUEST_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+#ifndef QT_NO_HTTP
+
+#include <private/qhttpnetworkheader_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHttpNetworkRequestPrivate;
+class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader
+{
+public:
+ enum Operation {
+ Options,
+ Get,
+ Head,
+ Post,
+ Put,
+ Delete,
+ Trace,
+ Connect
+ };
+
+ enum Priority {
+ HighPriority,
+ NormalPriority,
+ LowPriority
+ };
+
+ QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority);
+ QHttpNetworkRequest(const QHttpNetworkRequest &other);
+ virtual ~QHttpNetworkRequest();
+ QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other);
+ bool operator==(const QHttpNetworkRequest &other) const;
+
+ QUrl url() const;
+ void setUrl(const QUrl &url);
+
+ int majorVersion() const;
+ int minorVersion() const;
+
+ qint64 contentLength() const;
+ void setContentLength(qint64 length);
+
+ QList<QPair<QByteArray, QByteArray> > header() const;
+ QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
+ void setHeaderField(const QByteArray &name, const QByteArray &data);
+
+ Operation operation() const;
+ void setOperation(Operation operation);
+
+ Priority priority() const;
+ void setPriority(Priority priority);
+
+ QIODevice *data() const;
+ void setData(QIODevice *data);
+
+private:
+ QSharedDataPointer<QHttpNetworkRequestPrivate> d;
+ friend class QHttpNetworkRequestPrivate;
+ friend class QHttpNetworkConnectionPrivate;
+};
+
+
+class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate
+{
+public:
+ QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
+ QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl());
+ QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other);
+ ~QHttpNetworkRequestPrivate();
+ bool operator==(const QHttpNetworkRequestPrivate &other) const;
+ QByteArray methodName() const;
+ QByteArray uri(bool throughProxy) const;
+
+ static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy);
+
+ QHttpNetworkRequest::Operation operation;
+ QHttpNetworkRequest::Priority priority;
+ mutable QIODevice *data;
+ bool autoDecompress;
+};
+
+
+QT_END_NAMESPACE
+
+//Q_DECLARE_METATYPE(QHttpNetworkRequest)
+
+#endif // QT_NO_HTTP
+
+
+#endif // QHTTPNETWORKREQUEST_H
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 4b41aa7..a52b5a0 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -527,8 +527,10 @@ void QNetworkAccessHttpBackend::postRequest()
foreach (const QByteArray &header, headers)
httpRequest.setHeaderField(header, request().rawHeader(header));
- if (loadedFromCache)
+ if (loadedFromCache) {
+ QNetworkAccessBackend::finished();
return; // no need to send the request! :)
+ }
httpReply = http->sendRequest(httpRequest);
httpReply->setParent(this);
@@ -767,8 +769,12 @@ void QNetworkAccessHttpBackend::replyHeaderChanged()
for (; it != end; ++it) {
QByteArray value = rawHeader(it->first);
- if (!value.isEmpty())
- value += ", ";
+ if (!value.isEmpty()) {
+ if (it->first.toLower() == "set-cookie")
+ value += "\n";
+ else
+ value += ", ";
+ }
value += it->second;
setRawHeader(it->first, value);
}
@@ -886,8 +892,6 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m
if (status < 100)
status = 200; // fake it
- checkForRedirect(status);
-
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, status);
setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute));
setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true);
@@ -898,6 +902,8 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m
for ( ; it != end; ++it)
setRawHeader(it->first, it->second);
+ checkForRedirect(status);
+
writeDownstreamData(contents);
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes";
@@ -951,6 +957,7 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
QList<QByteArray> newHeaders = rawHeaderList();
foreach (QByteArray header, newHeaders) {
+ QByteArray originalHeader = header;
header = header.toLower();
bool hop_by_hop =
(header == "connection"
@@ -974,19 +981,32 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo
continue;
}
+ it = cacheHeaders.findRawHeader(header);
+ if (it != cacheHeaders.rawHeaders.constEnd()) {
+ // Match the behavior of Firefox and assume Cache-Control: "no-transform"
+ if (header == "content-encoding"
+ || header == "content-range"
+ || header == "content-type")
+ continue;
+
+ // For MS servers that send "Content-Length: 0" on 304 responses
+ // ignore this too
+ if (header == "content-length")
+ continue;
+ }
+
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
QByteArray n = rawHeader(header);
QByteArray o;
- it = cacheHeaders.findRawHeader(header);
if (it != cacheHeaders.rawHeaders.constEnd())
o = (*it).second;
- if (n != o && header != "Date") {
+ if (n != o && header != "date") {
qDebug() << "replacing" << header;
qDebug() << "new" << n;
qDebug() << "old" << o;
}
#endif
- cacheHeaders.setRawHeader(header, rawHeader(header));
+ cacheHeaders.setRawHeader(originalHeader, rawHeader(header));
}
metaData.setRawHeaders(cacheHeaders.rawHeaders);
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 1235960..01a743b 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -49,6 +49,7 @@
#include "QtCore/qlist.h"
#include "QtCore/qlocale.h"
#include "QtCore/qstring.h"
+#include "QtCore/qstringlist.h"
#include "QtCore/qurl.h"
#include "private/qobject_p.h"
@@ -163,7 +164,7 @@ bool QNetworkCookie::operator==(const QNetworkCookie &other) const
return true;
return d->name == other.d->name &&
d->value == other.d->value &&
- d->expirationDate == other.d->expirationDate &&
+ d->expirationDate.toUTC() == other.d->expirationDate.toUTC() &&
d->domain == other.d->domain &&
d->path == other.d->path &&
d->secure == other.d->secure &&
@@ -513,6 +514,392 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const
return result;
}
+static const char zones[] =
+ "pst\0" // -8
+ "pdt\0"
+ "mst\0" // -7
+ "mdt\0"
+ "cst\0" // -6
+ "cdt\0"
+ "est\0" // -5
+ "edt\0"
+ "ast\0" // -4
+ "nst\0" // -3
+ "gmt\0" // 0
+ "utc\0"
+ "bst\0"
+ "met\0" // 1
+ "eet\0" // 2
+ "jst\0" // 9
+ "\0";
+static int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 };
+
+static const char months[] =
+ "jan\0"
+ "feb\0"
+ "mar\0"
+ "apr\0"
+ "may\0"
+ "jun\0"
+ "jul\0"
+ "aug\0"
+ "sep\0"
+ "oct\0"
+ "nov\0"
+ "dec\0"
+ "\0";
+
+static inline bool isNumber(char s)
+{ return s >= '0' && s <= '9'; }
+
+static inline bool isTerminator(char c)
+{ return c == '\n' || c == '\r'; }
+
+static inline bool isValueSeparator(char c)
+{ return isTerminator(c) || c == ';'; }
+
+static inline bool isWhitespace(char c)
+{ return c == ' ' || c == '\t'; }
+
+static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, int size)
+{
+ if (dateString[at] < 'a' || dateString[at] > 'z')
+ return false;
+ if (val == -1 && dateString.length() >= at + 3) {
+ int j = 0;
+ int i = 0;
+ while (i <= size) {
+ const char *str = array + i;
+ if (str[0] == dateString[at]
+ && str[1] == dateString[at + 1]
+ && str[2] == dateString[at + 2]) {
+ val = j;
+ return true;
+ }
+ i += strlen(str) + 1;
+ ++j;
+ }
+ }
+ return false;
+}
+
+//#define PARSEDATESTRINGDEBUG
+
+#define ADAY 1
+#define AMONTH 2
+#define AYEAR 4
+
+/*
+ Parse all the date formats that Firefox can.
+
+ The official format is:
+ expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT
+
+ But browsers have been supporting a very wide range of date
+ strings. To work on many sites we need to support more then
+ just the official date format.
+
+ For reference see Firefox's PR_ParseTimeStringToExplodedTime in
+ prtime.c. The Firefox date parser is coded in a very complex way
+ and is slightly over ~700 lines long. While this implementation
+ will be slightly slower for the non standard dates it is smaller,
+ more readable, and maintainable.
+
+ Or in their own words:
+ "} // else what the hell is this."
+*/
+static QDateTime parseDateString(const QByteArray &dateString)
+{
+ QTime time;
+ // placeholders for values when we are not sure it is a year, month or day
+ int unknown[3] = {-1, -1, -1};
+ int month = -1;
+ int day = -1;
+ int year = -1;
+ int zoneOffset = -1;
+
+ // hour:minute:second.ms pm
+ QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)"));
+
+ int at = 0;
+ while (at < dateString.length()) {
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << dateString.mid(at);
+#endif
+ bool isNum = isNumber(dateString[at]);
+
+ // Month
+ if (!isNum
+ && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) {
+ ++month;
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Month:" << month;
+#endif
+ at += 3;
+ continue;
+ }
+ // Zone
+ if (!isNum
+ && zoneOffset == -1
+ && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) {
+ int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1;
+ zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60;
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Zone:" << month;
+#endif
+ at += 3;
+ continue;
+ }
+ // Zone offset
+ if (!isNum
+ && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt
+ && (dateString[at] == '+' || dateString[at] == '-')
+ && (at == 0
+ || isWhitespace(dateString[at - 1])
+ || dateString[at - 1] == ','
+ || (at >= 3
+ && (dateString[at - 3] == 'g')
+ && (dateString[at - 2] == 'm')
+ && (dateString[at - 1] == 't')))) {
+
+ int end = 1;
+ while (end < 5 && dateString.length() > at+end
+ && dateString[at + end] >= '0' && dateString[at + end] <= '9')
+ ++end;
+ int minutes = 0;
+ int hours = 0;
+ switch (end - 1) {
+ case 4:
+ minutes = atoi(dateString.mid(at + 3, 2).constData());
+ // fall through
+ case 2:
+ hours = atoi(dateString.mid(at + 1, 2).constData());
+ break;
+ case 1:
+ hours = atoi(dateString.mid(at + 1, 1).constData());
+ break;
+ default:
+ at += end;
+ continue;
+ }
+ if (end != 1) {
+ int sign = dateString[at] == '-' ? -1 : 1;
+ zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60));
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Zone offset:" << zoneOffset << hours << minutes;
+#endif
+ at += end;
+ continue;
+ }
+ }
+
+ // Time
+ if (isNum && time.isNull()
+ && dateString.length() >= at + 3
+ && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) {
+ // While the date can be found all over the string the format
+ // for the time is set and a nice regexp can be used.
+ int pos = timeRx.indexIn(QLatin1String(dateString), at);
+ if (pos != -1) {
+ QStringList list = timeRx.capturedTexts();
+ int h = atoi(list.at(1).toLatin1().constData());
+ int m = atoi(list.at(2).toLatin1().constData());
+ int s = atoi(list.at(4).toLatin1().constData());
+ int ms = atoi(list.at(6).toLatin1().constData());
+ if (h < 12 && !list.at(9).isEmpty())
+ if (list.at(9) == QLatin1String("pm"))
+ h += 12;
+ time = QTime(h, m, s, ms);
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Time:" << list << timeRx.matchedLength();
+#endif
+ at += timeRx.matchedLength();
+ continue;
+ }
+ }
+
+ // 4 digit Year
+ if (isNum
+ && year == -1
+ && dateString.length() >= at + 3) {
+ if (isNumber(dateString[at + 1])
+ && isNumber(dateString[at + 2])
+ && isNumber(dateString[at + 3])) {
+ year = atoi(dateString.mid(at, 4).constData());
+ at += 4;
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Year:" << year;
+#endif
+ continue;
+ }
+ }
+
+ // a one or two digit number
+ // Could be month, day or year
+ if (isNum) {
+ int length = 1;
+ if (dateString.length() > at + 1
+ && isNumber(dateString[at + 1]))
+ ++length;
+ int x = atoi(dateString.mid(at, length).constData());
+ if (year == -1 && (x > 31 || x == 0)) {
+ year = x;
+ } else {
+ if (unknown[0] == -1) unknown[0] = x;
+ else if (unknown[1] == -1) unknown[1] = x;
+ else if (unknown[2] == -1) unknown[2] = x;
+ }
+ at += length;
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Saving" << x;
+#endif
+ continue;
+ }
+
+ // Unknown character, typically a weekday such as 'Mon'
+ ++at;
+ }
+
+ // Once we are done parsing the string take the digits in unknown
+ // and determine which is the unknown year/month/day
+
+ int couldBe[3] = { 0, 0, 0 };
+ int unknownCount = 3;
+ for (int i = 0; i < unknownCount; ++i) {
+ if (unknown[i] == -1) {
+ couldBe[i] = ADAY | AYEAR | AMONTH;
+ unknownCount = i;
+ continue;
+ }
+
+ if (unknown[i] >= 1)
+ couldBe[i] = ADAY;
+
+ if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12)
+ couldBe[i] |= AMONTH;
+
+ if (year == -1)
+ couldBe[i] |= AYEAR;
+ }
+
+ // For any possible day make sure one of the values that could be a month
+ // can contain that day.
+ // For any possible month make sure one of the values that can be a
+ // day that month can have.
+ // Example: 31 11 06
+ // 31 can't be a day because 11 and 6 don't have 31 days
+ for (int i = 0; i < unknownCount; ++i) {
+ int currentValue = unknown[i];
+ bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29;
+ bool findMatchingDay = couldBe[i] & AMONTH;
+ if (!findMatchingMonth || !findMatchingDay)
+ continue;
+ for (int j = 0; j < 3; ++j) {
+ if (j == i)
+ continue;
+ for (int k = 0; k < 2; ++k) {
+ if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH)))
+ continue;
+ else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY)))
+ continue;
+ int m = currentValue;
+ int d = unknown[j];
+ if (k == 0)
+ qSwap(m, d);
+ if (m == -1) m = month;
+ bool found = true;
+ switch(m) {
+ case 2:
+ // When we get 29 and the year ends up having only 28
+ // See date.isValid below
+ // Example: 29 23 Feb
+ if (d <= 29)
+ found = false;
+ break;
+ case 4: case 6: case 9: case 11:
+ if (d <= 30)
+ found = false;
+ break;
+ default:
+ if (d > 0 && d <= 31)
+ found = false;
+ }
+ if (k == 0) findMatchingMonth = found;
+ else if (k == 1) findMatchingDay = found;
+ }
+ }
+ if (findMatchingMonth)
+ couldBe[i] &= ~ADAY;
+ if (findMatchingDay)
+ couldBe[i] &= ~AMONTH;
+ }
+
+ // First set the year/month/day that have been deduced
+ // and reduce the set as we go along to deduce more
+ for (int i = 0; i < unknownCount; ++i) {
+ int unset = 0;
+ for (int j = 0; j < 3; ++j) {
+ if (couldBe[j] == ADAY && day == -1) {
+ day = unknown[j];
+ unset |= ADAY;
+ } else if (couldBe[j] == AMONTH && month == -1) {
+ month = unknown[j];
+ unset |= AMONTH;
+ } else if (couldBe[j] == AYEAR && year == -1) {
+ year = unknown[j];
+ unset |= AYEAR;
+ } else {
+ // common case
+ break;
+ }
+ couldBe[j] &= ~unset;
+ }
+ }
+
+ // Now fallback to a standardized order to fill in the rest with
+ for (int i = 0; i < unknownCount; ++i) {
+ if (couldBe[i] & AMONTH && month == -1) month = unknown[i];
+ else if (couldBe[i] & ADAY && day == -1) day = unknown[i];
+ else if (couldBe[i] & AYEAR && year == -1) year = unknown[i];
+ }
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Final set" << year << month << day;
+#endif
+
+ if (year == -1 || month == -1 || day == -1) {
+#ifdef PARSEDATESTRINGDEBUG
+ qDebug() << "Parser failure" << year << month << day;
+#endif
+ return QDateTime();
+ }
+
+ // Y2k behavior
+ int y2k = 0;
+ if (year < 70)
+ y2k = 2000;
+ else if (year < 100)
+ y2k = 1900;
+
+ QDate date(year + y2k, month, day);
+
+ // When we were given a bad cookie that when parsed
+ // set the day to 29 and the year to one that doesn't
+ // have the 29th of Feb rather then adding the extra
+ // complicated checking earlier just swap here.
+ // Example: 29 23 Feb
+ if (!date.isValid())
+ date = QDate(day + y2k, month, year);
+
+ QDateTime dateTime(date, time, Qt::UTC);
+
+ if (zoneOffset != -1) {
+ dateTime = dateTime.addSecs(zoneOffset);
+ }
+ if (!dateTime.isValid())
+ return QDateTime();
+ return dateTime;
+}
+
/*!
Parses the cookie string \a cookieString as received from a server
response in the "Set-Cookie:" header. If there's a parsing error,
@@ -543,17 +930,23 @@ QList<QNetworkCookie> QNetworkCookie::parseCookies(const QByteArray &cookieStrin
while (position < length) {
QNetworkCookie cookie;
+ // When there are multiple SetCookie headers they are join with a new line
+ // \n will always be the start of a new cookie
+ int endOfSetCookie = cookieString.indexOf('\n', position);
+ if (endOfSetCookie == -1)
+ endOfSetCookie = length;
+
// The first part is always the "NAME=VALUE" part
QPair<QByteArray,QByteArray> field = nextField(cookieString, position);
if (field.first.isEmpty() || field.second.isNull())
// parsing error
- return QList<QNetworkCookie>();
+ break;
cookie.setName(field.first);
cookie.setValue(field.second);
position = nextNonWhitespace(cookieString, position);
bool endOfCookie = false;
- while (!endOfCookie && position < length)
+ while (!endOfCookie && position < endOfSetCookie)
switch (cookieString.at(position++)) {
case ',':
// end of the cookie
@@ -566,64 +959,20 @@ QList<QNetworkCookie> QNetworkCookie::parseCookies(const QByteArray &cookieStrin
field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive
if (field.first == "expires") {
- static const char dateFormats[] =
- "d-MMM-yyyy hh:mm:ss\0"
- "d MMM yyyy hh:mm:ss\0"
- "d-MMM-yy hh:mm:ss\0"
- "\0";
-
- // expires is a special case because it contains a naked comma
- // and naked spaces. The format is:
- // expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT
- // but we also accept standard HTTP dates
-
- // make sure we're at the comma
- if (position >= length || cookieString.at(position) != ',')
- // invalid cookie string
- return QList<QNetworkCookie>();
-
- ++position;
+ position -= field.second.length();
int end;
for (end = position; end < length; ++end)
- if (cookieString.at(end) == ',' || cookieString.at(end) == ';')
+ if (isValueSeparator(cookieString.at(end)))
break;
- QByteArray datestring = cookieString.mid(position, end - position).trimmed();
+ QByteArray dateString = cookieString.mid(position, end - position).trimmed();
position = end;
- if (datestring.endsWith(" GMT") || datestring.endsWith(" UTC"))
- datestring.chop(4);
- else if (datestring.endsWith(" +0000"))
- datestring.chop(6);
-
- size_t i = 0;
- int j = 0;
- QLocale cLocale = QLocale::c();
- QDateTime dt;
- do {
- QLatin1String df(dateFormats + i);
- i += strlen(dateFormats + i) + 1;
-
-#ifndef QT_NO_DATESTRING
- dt = cLocale.toDateTime(QString::fromLatin1(datestring), df);
-
- // some cookies are set with a two-digit year
- // (although this is not allowed); this is interpreted as a year
- // in the 20th century by QDateTime.
- // Work around this case here (assuming 00-69 is 21st century,
- // 70-99 is 20th century)
- QDate date = dt.date();
- if (j == 2 && date.year() >= 1900 && date.year() < 1970)
- dt = dt.addYears(100);
- if (date.year() >= 0 && date.year() < 100)
- dt = dt.addYears(1900);
-#endif
- j++;
- } while (!dt.isValid() && i <= sizeof dateFormats - 1);
- if (!dt.isValid())
- // invalid cookie string
- return QList<QNetworkCookie>();
-
- dt.setTimeSpec(Qt::UTC);
+ QDateTime dt = parseDateString(dateString.toLower());
+ if (!dt.isValid()) {
+ cookie = QNetworkCookie();
+ endOfCookie = true;
+ continue;
+ }
cookie.setExpirationDate(dt);
} else if (field.first == "domain") {
QByteArray rawDomain = field.second;
@@ -664,9 +1013,12 @@ QList<QNetworkCookie> QNetworkCookie::parseCookies(const QByteArray &cookieStrin
}
position = nextNonWhitespace(cookieString, position);
+ if (position > endOfSetCookie)
+ endOfCookie = true;
}
- result += cookie;
+ if (!cookie.name().isEmpty())
+ result += cookie;
}
return result;
diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp
index fa0fccb..93360c8 100644
--- a/src/network/access/qnetworkdiskcache.cpp
+++ b/src/network/access/qnetworkdiskcache.cpp
@@ -253,7 +253,8 @@ void QNetworkDiskCachePrivate::storeItem(QCacheItem *cacheItem)
// ### use atomic rename rather then remove & rename
if (cacheItem->file->rename(fileName))
currentCacheSize += cacheItem->file->size();
- cacheItem->file->setAutoRemove(true);
+ else
+ cacheItem->file->setAutoRemove(true);
}
if (cacheItem->metaData.url() == lastItem.metaData.url())
lastItem.reset();
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index eaa572f..79c3d1a 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -131,27 +131,37 @@ void QNetworkReplyImplPrivate::_q_copyReadyRead()
if (!copyDevice && !q->isOpen())
return;
- qint64 bytesToRead = nextDownstreamBlockSize();
- if (bytesToRead == 0)
- // we'll be called again, eventually
- return;
+ forever {
+ qint64 bytesToRead = nextDownstreamBlockSize();
+ if (bytesToRead == 0)
+ // we'll be called again, eventually
+ break;
- bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable());
- char *ptr = readBuffer.reserve(bytesToRead);
- qint64 bytesActuallyRead = copyDevice->read(ptr, bytesToRead);
- if (bytesActuallyRead == -1) {
- readBuffer.chop(bytesToRead);
- backendNotify(NotifyCopyFinished);
- return;
- }
+ bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable());
+ char *ptr = readBuffer.reserve(bytesToRead);
+ qint64 bytesActuallyRead = copyDevice->read(ptr, bytesToRead);
+ if (bytesActuallyRead == -1) {
+ readBuffer.chop(bytesToRead);
+ backendNotify(NotifyCopyFinished);
+ return;
+ }
- if (bytesActuallyRead != bytesToRead)
- readBuffer.chop(bytesToRead - bytesActuallyRead);
+ if (bytesActuallyRead != bytesToRead)
+ readBuffer.chop(bytesToRead - bytesActuallyRead);
- if (!copyDevice->isSequential() && copyDevice->atEnd())
- backendNotify(NotifyCopyFinished);
+ if (!copyDevice->isSequential() && copyDevice->atEnd()) {
+ backendNotify(NotifyCopyFinished);
+ break;
+ }
+
+ bytesDownloaded += bytesActuallyRead;
+ }
+
+ if (bytesDownloaded == lastBytesDownloaded) {
+ // we didn't read anything
+ return;
+ }
- bytesDownloaded += bytesActuallyRead;
lastBytesDownloaded = bytesDownloaded;
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
emit q->downloadProgress(bytesDownloaded,
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 4f477bd..c9161f8 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -52,7 +52,7 @@
QT_BEGIN_NAMESPACE
-#include <../3rdparty/des/des.cpp>
+#include "../../3rdparty/des/des.cpp"
static QByteArray qNtlmPhase1();
static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index fc43369..b225c17 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -435,7 +435,7 @@ void QNetmaskAddress::setPrefixLength(QAbstractSocket::NetworkLayerProtocol prot
The class also supports common predefined addresses: \l Null, \l
LocalHost, \l LocalHostIPv6, \l Broadcast, and \l Any.
- \sa QTcpSocket, QTcpServer, QUdpSocket
+ \sa QHostInfo, QTcpSocket, QTcpServer, QUdpSocket
*/
/*! \enum QHostAddress::SpecialAddress
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index b6d00ce..02a6f97 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -42,6 +42,7 @@
#ifndef QHOSTADDRESS_H
#define QHOSTADDRESS_H
+#include <QtCore/qpair.h>
#include <QtCore/qstring.h>
#include <QtNetwork/qabstractsocket.h>
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 9540c18..de97629 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -173,14 +173,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP()
interfaces << iface;
iface->index = 0;
- if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex))
+ if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex) && ptr->Ipv6IfIndex != 0)
iface->index = ptr->Ipv6IfIndex;
else if (ptr->IfIndex != 0)
iface->index = ptr->IfIndex;
iface->flags = QNetworkInterface::CanBroadcast;
- if (ptr->OperStatus == IfOperStatusUp)
- iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
+ if (ptr->OperStatus == IfOperStatusUp)
+ iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
if ((ptr->Flags & IP_ADAPTER_NO_MULTICAST) == 0)
iface->flags |= QNetworkInterface::CanMulticast;
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index 31c2a33..16d18cf 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -102,6 +102,8 @@ typedef struct {
#define WINHTTP_NO_PROXY_NAME NULL
#define WINHTTP_NO_PROXY_BYPASS NULL
+QT_BEGIN_NAMESPACE
+
typedef BOOL (WINAPI * PtrWinHttpGetProxyForUrl)(HINTERNET, LPCWSTR, WINHTTP_AUTOPROXY_OPTIONS*, WINHTTP_PROXY_INFO*);
typedef HINTERNET (WINAPI * PtrWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR,DWORD);
typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
@@ -113,6 +115,7 @@ static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfigura
static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0;
static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0;
+
static QStringList splitSpaceSemicolon(const QString &source)
{
QStringList list;
@@ -407,4 +410,6 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
#endif
+QT_END_NAMESPACE
+
#endif
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 910e30a..f9750f2 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1263,7 +1263,7 @@ void QAbstractSocket::connectToHostImplementation(const QString &hostName, quint
(int) openMode);
#endif
- if (d->state == ConnectedState || d->state == ConnectingState) {
+ if (d->state == ConnectedState || d->state == ConnectingState || d->state == ClosingState) {
qWarning("QAbstractSocket::connectToHost() called when already connecting/connected to \"%s\"", qPrintable(hostName));
return;
}
@@ -2279,7 +2279,7 @@ void QAbstractSocket::disconnectFromHostImplementation()
emit delayedCloseFinished(); // compat signal
#endif
// only emit disconnected if we were connected before
- if (previousState == ConnectedState || ClosingState)
+ if (previousState == ConnectedState || previousState == ClosingState)
emit disconnected();
d->localPort = 0;
diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h
index dd48d0a..781d3da 100644
--- a/src/network/socket/qlocalsocket_p.h
+++ b/src/network/socket/qlocalsocket_p.h
@@ -192,6 +192,7 @@ public:
void _q_error(QAbstractSocket::SocketError newError);
void _q_connectToSocket();
void _q_abortConnectionAttempt();
+ void cancelDelayedConnect();
QSocketNotifier *delayConnect;
QTimer *connectTimer;
int connectingSocket;
diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp
index a375e9b..38643f1 100644
--- a/src/network/socket/qlocalsocket_unix.cpp
+++ b/src/network/socket/qlocalsocket_unix.cpp
@@ -322,11 +322,8 @@ void QLocalSocketPrivate::_q_connectToSocket()
}
// connected!
- if (delayConnect) {
- delayConnect->setEnabled(false);
- delete delayConnect;
- delayConnect = 0;
- }
+ cancelDelayedConnect();
+
serverName = connectingName;
fullServerName = connectingPathName;
if (unixSocket.setSocketDescriptor(connectingSocket,
@@ -373,6 +370,18 @@ void QLocalSocketPrivate::_q_abortConnectionAttempt()
q->close();
}
+void QLocalSocketPrivate::cancelDelayedConnect()
+{
+ if (delayConnect) {
+ delayConnect->setEnabled(false);
+ delete delayConnect;
+ delayConnect = 0;
+ connectTimer->stop();
+ delete connectTimer;
+ connectTimer = 0;
+ }
+}
+
quintptr QLocalSocket::socketDescriptor() const
{
Q_D(const QLocalSocket);
@@ -419,14 +428,7 @@ void QLocalSocket::close()
{
Q_D(QLocalSocket);
d->unixSocket.close();
- if (d->delayConnect) {
- d->delayConnect->setEnabled(false);
- delete d->delayConnect;
- d->delayConnect = 0;
- d->connectTimer->stop();
- delete d->connectTimer;
- d->connectTimer = 0;
- }
+ d->cancelDelayedConnect();
if (d->connectingSocket != -1)
::close(d->connectingSocket);
d->connectingSocket = -1;
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 534f7ec..cc372a6 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -506,26 +506,11 @@ int QNativeSocketEnginePrivate::nativeAccept()
qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
{
- /*
- Apparently, there is not consistency among different operating
- systems on how to use FIONREAD.
-
- FreeBSD, Linux and Solaris all expect the 3rd argument to
- ioctl() to be an int, which is normally 32-bit even on 64-bit
- machines.
-
- IRIX, on the other hand, expects a size_t, which is 64-bit on
- 64-bit machines.
-
- So, the solution is to use size_t initialized to zero to make
- sure all bits are set to zero, preventing underflow with the
- FreeBSD/Linux/Solaris ioctls.
- */
- size_t nbytes = 0;
+ int nbytes = 0;
// gives shorter than true amounts on Unix domain sockets.
qint64 available = 0;
if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
- available = (qint64) *((int *) &nbytes);
+ available = (qint64) nbytes;
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeBytesAvailable() == %lli", available);
@@ -884,15 +869,15 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co
if (timeout > 0) {
// recalculate the timeout
- timeout -= timer.elapsed();
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
- if (timeout < 0) {
+ int t = timeout - timer.elapsed();
+ if (t < 0) {
// oops, timeout turned negative?
retval = -1;
break;
}
+
+ tv.tv_sec = t / 1000;
+ tv.tv_usec = (t % 1000) * 1000;
}
} while (true);
@@ -927,15 +912,15 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c
if (timeout > 0) {
// recalculate the timeout
- timeout -= timer.elapsed();
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
- if (timeout < 0) {
+ int t = timeout - timer.elapsed();
+ if (t < 0) {
// oops, timeout turned negative?
ret = -1;
break;
}
+
+ tv.tv_sec = t / 1000;
+ tv.tv_usec = (t % 1000) * 1000;
}
} while (true);
if (ret <= 0)
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 48d7caf..78aaddb 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -25,18 +25,16 @@ HEADERS += qgl.h \
qglcolormap.h \
qglpixelbuffer.h \
qglframebufferobject.h \
- qglpixmapfilter_p.h
SOURCES += qgl.cpp \
qglcolormap.cpp \
qglpixelbuffer.cpp \
qglframebufferobject.cpp \
qglextensions.cpp \
- qglpixmapfilter.cpp
!contains(QT_CONFIG, opengles2) {
- HEADERS += qpaintengine_opengl_p.h
- SOURCES += qpaintengine_opengl.cpp
+ HEADERS += qpaintengine_opengl_p.h qglpixmapfilter_p.h
+ SOURCES += qpaintengine_opengl.cpp qglpixmapfilter.cpp
}
contains(QT_CONFIG, opengles2) {
@@ -130,6 +128,10 @@ wince*: {
contains(QT_CONFIG,opengles1cl) {
QMAKE_LIBS += "libGLES_CL.lib"
}
+ contains(QT_CONFIG,opengles2) {
+ QMAKE_LIBS += "libGLESv2.lib"
+ }
+
} else {
QMAKE_LIBS += $$QMAKE_LIBS_OPENGL
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 2d90342..b4a0e5c 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2615,6 +2615,10 @@ const QGLContext* QGLContext::currentContext()
QGLWidget. This will side-step the issue altogether, and is what
we recommend for users that need this kind of functionality.
+ On Mac OS X, when Qt is built with Cocoa support, a QGLWidget
+ can't have any sibling widgets placed ontop of itself. This is due
+ to limitations in the Cocoa API and is not supported by Apple.
+
\section1 Overlays
The QGLWidget creates a GL overlay context in addition to the
@@ -3230,6 +3234,10 @@ bool QGLWidget::event(QEvent *e)
update();
}
return true;
+# if defined(QT_MAC_USE_COCOA)
+ } else if (e->type() == QEvent::MacGLClearDrawable) {
+ d->glcx->d_ptr->clearDrawable();
+# endif
}
#endif
diff --git a/src/opengl/qgl_cl_p.h b/src/opengl/qgl_cl_p.h
index e514ff5..c05a7d7 100644
--- a/src/opengl/qgl_cl_p.h
+++ b/src/opengl/qgl_cl_p.h
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
inline void glTexParameterf (GLenum target, GLenum pname, GLfloat param)
{
- glTexParameterx(target, pname, param);
+ glTexParameterx(target, pname, FLOAT2X(param));
}
inline void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm
index 314c659..1319396 100644
--- a/src/opengl/qgl_mac.mm
+++ b/src/opengl/qgl_mac.mm
@@ -87,29 +87,6 @@ QT_FORWARD_DECLARE_CLASS(QWidget)
QT_FORWARD_DECLARE_CLASS(QWidgetPrivate)
QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate)
-@interface QT_MANGLE_NAMESPACE(QCocoaOpenGLView) : QT_MANGLE_NAMESPACE(QCocoaView)
-{
-}
-- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
-@end
-
-@implementation QT_MANGLE_NAMESPACE(QCocoaOpenGLView)
-- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate
-{
- self = [super initWithQWidget:widget widgetPrivate:widgetprivate];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(_surfaceNeedsUpdate:)
- name:NSViewGlobalFrameDidChangeNotification
- object:self];
- return self;
-}
-
-- (void) _surfaceNeedsUpdate:(NSNotification*)notification
-{
- Q_UNUSED(notification);
- static_cast<QGLWidgetPrivate *>(qwidgetprivate)->glcx->updatePaintDevice();
-}
-@end
QT_BEGIN_NAMESPACE
void *qt_current_nsopengl_context()
@@ -435,6 +412,11 @@ void *QGLContextPrivate::tryFormat(const QGLFormat &format)
#endif
}
+void QGLContextPrivate::clearDrawable()
+{
+ [static_cast<NSOpenGLContext *>(cx) clearDrawable];
+}
+
/*!
\bold{Mac OS X only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
@@ -647,7 +629,7 @@ void QGLContext::updatePaintDevice()
// ideally we would use QWidget::isVisible(), but we get "invalid drawable" errors
if (![(NSWindow *)qt_mac_window_for(w) isVisible])
return;
- if ([static_cast<NSOpenGLContext *>(d->cx) view] != view)
+ if ([static_cast<NSOpenGLContext *>(d->cx) view] != view && ![view isHidden])
[static_cast<NSOpenGLContext *>(d->cx) setView:view];
} else if (d->paintDevice->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap *>(d->paintDevice);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index b8bbeaf..16aaa96 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -234,6 +234,7 @@ public:
#if defined(Q_WS_MAC)
bool update;
void *tryFormat(const QGLFormat &format);
+ void clearDrawable();
#endif
QGLFormat glFormat;
QGLFormat reqFormat;
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index fb22272..c362b7e 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -48,6 +48,10 @@
#include <qlibrary.h>
#include <qimage.h>
+#ifdef QT_OPENGL_ES_1_CL
+#include "qgl_cl_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
index 964efa2..5390fd1 100644
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ b/src/opengl/qglpixelbuffer_egl.cpp
@@ -47,6 +47,10 @@
#include <qimage.h>
#include <private/qgl_p.h>
+#ifdef QT_OPENGL_ES_1_CL
+#include "qgl_cl_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
#ifdef EGL_BIND_TO_TEXTURE_RGBA
@@ -188,8 +192,8 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->req_size.width(), d->req_size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(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_MIN_FILTER, GL_LINEAR);
return texture;
#else
return 0;
diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm
index 14941ab..9a679b1 100644
--- a/src/opengl/qglpixelbuffer_mac.mm
+++ b/src/opengl/qglpixelbuffer_mac.mm
@@ -308,10 +308,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
- [static_cast<NSOpenGLContext *>(d->share_ctx)
- setTextureImageToPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(d->pbuf)
- colorBuffer:GL_FRONT];
- glBindTexture(GL_TEXTURE_2D, texture); // updates texture target
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -322,8 +318,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
- aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT);
- glBindTexture(GL_TEXTURE_2D, texture); // updates texture target
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
index e81a576..e3228cc 100644
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ b/src/opengl/qglpixelbuffer_win.cpp
@@ -43,7 +43,7 @@
#include <qgl.h>
#include <private/qgl_p.h>
-#include <qglpixelbuffer_p.h>
+#include <private/qglpixelbuffer_p.h>
#include <qimage.h>
#include <qdebug.h>
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 96abe18..88fd379 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -1983,7 +1983,7 @@ public:
void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap)
{
// On OpenGL ES we convert the trap to 2 triangles
-#ifndef QT_OPENGL_ES_1
+#ifndef QT_OPENGL_ES
if (size > allocated - 8) {
#else
if (size > allocated - 12) {
@@ -1994,31 +1994,31 @@ void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap)
QGLTrapezoid t = toGLTrapezoid(trap);
-#ifndef QT_OPENGL_ES_1
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.topRightX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
- vertices[size++] = t.bottomLeftX;
- vertices[size++] = t.bottom;
+#ifndef QT_OPENGL_ES
+ vertices[size++] = f2vt(t.topLeftX);
+ vertices[size++] = f2vt(t.top);
+ vertices[size++] = f2vt(t.topRightX);
+ vertices[size++] = f2vt(t.top);
+ vertices[size++] = f2vt(t.bottomRightX);
+ vertices[size++] = f2vt(t.bottom);
+ vertices[size++] = f2vt(t.bottomLeftX);
+ vertices[size++] = f2vt(t.bottom);
#else
// First triangle
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.topRightX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
+ vertices[size++] = f2vt(t.topLeftX);
+ vertices[size++] = f2vt(t.top);
+ vertices[size++] = f2vt(t.topRightX);
+ vertices[size++] = f2vt(t.top);
+ vertices[size++] = f2vt(t.bottomRightX);
+ vertices[size++] = f2vt(t.bottom);
// Second triangle
- vertices[size++] = t.bottomLeftX;
- vertices[size++] = t.bottom;
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
+ vertices[size++] = f2vt(t.bottomLeftX);
+ vertices[size++] = f2vt(t.bottom);
+ vertices[size++] = f2vt(t.topLeftX);
+ vertices[size++] = f2vt(t.top);
+ vertices[size++] = f2vt(t.bottomRightX);
+ vertices[size++] = f2vt(t.bottom);
#endif
}
@@ -4139,12 +4139,13 @@ void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path)
enableClipping();
}
+extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+
void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_cache)
{
QBrush old_brush = cbrush;
cbrush = cpen.brush();
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
qreal txscale = 1;
if (cpen.isCosmetic() || (qt_scaleForTransform(matrix, &txscale) && txscale != 1)) {
QTransform temp = matrix;
@@ -5327,6 +5328,9 @@ void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType *
Q_Q(QOpenGLPaintEngine);
QGL_FUNC_CONTEXT;
+ if (current_style == Qt::NoBrush)
+ return;
+
DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Using compositing program: fragment_brush ="
<< fragment_brush << ", fragment_composition_mode =" << fragment_composition_mode;
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 83bd80b..837ccf2 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -76,12 +76,18 @@
#define GLX_SAMPLES_ARB 100001
#endif
+#ifdef QT_OPENGL_ES_1_CL
+#include "qgl_cl_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
//
// QGLGraphicsSystem
//
-
+#ifdef Q_WS_WIN
+Q_GUI_EXPORT bool qt_win_owndc_required;
+#endif
QGLGraphicsSystem::QGLGraphicsSystem()
: QGraphicsSystem()
{
@@ -160,7 +166,6 @@ QGLGraphicsSystem::QGLGraphicsSystem()
#elif defined(Q_WS_WIN)
QGLWindowSurface::surfaceFormat.setDoubleBuffer(false);
- Q_GUI_EXPORT bool qt_win_owndc_required;
qt_win_owndc_required = true;
#endif
}
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
index 96eb536..89a289c 100644
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ b/src/plugins/gfxdrivers/directfb/directfb.pro
@@ -12,6 +12,8 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers
#DEFINES += QT_NO_DIRECTFB_PREALLOCATED
#DEFINES += QT_NO_DIRECTFB_MOUSE
#DEFINES += QT_NO_DIRECTFB_KEYBOARD
+#DEFINES += QT_DIRECTFB_TIMING
+#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION
target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
INSTALLS += target
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
index d1802e4..2a2ef5c 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
@@ -44,8 +44,13 @@
#include "qdirectfbscreen.h"
#include "qdirectfbpaintdevice.h"
+QDirectFBPaintDevice::~QDirectFBPaintDevice()
+{
+ delete lockedImage;
+}
-IDirectFBSurface *QDirectFBPaintDevice::directFbSurface() const
+
+IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const
{
return dfbSurface;
}
@@ -59,9 +64,6 @@ void QDirectFBPaintDevice::lockDirectFB() {
void *mem;
int w, h;
- int bpl;
- DFBSurfacePixelFormat format;
-
DFBResult result = dfbSurface->Lock(dfbSurface, DSLF_WRITE, &mem, &bpl);
if (result != DFB_OK || !mem) {
DirectFBError("QDirectFBPixmapData::buffer()", result);
@@ -69,16 +71,14 @@ void QDirectFBPaintDevice::lockDirectFB() {
}
dfbSurface->GetSize(dfbSurface, &w, &h);
- dfbSurface->GetPixelFormat(dfbSurface, &format);
-
lockedImage = new QImage(static_cast<uchar*>(mem), w, h, bpl,
- QDirectFBScreen::getImageFormat(format));
+ QDirectFBScreen::getImageFormat(dfbSurface));
}
void QDirectFBPaintDevice::unlockDirectFB()
{
- if (!lockedImage)
+ if (!lockedImage || !QDirectFBScreen::instance())
return;
dfbSurface->Unlock(dfbSurface);
@@ -98,19 +98,20 @@ void* QDirectFBPaintDevice::memory() const
QImage::Format QDirectFBPaintDevice::format() const
{
- DFBSurfacePixelFormat dfbFormat;
- dfbSurface->GetPixelFormat(dfbSurface, &dfbFormat);
- return QDirectFBScreen::getImageFormat(dfbFormat);
+ return QDirectFBScreen::getImageFormat(dfbSurface);
}
int QDirectFBPaintDevice::bytesPerLine() const
{
- // Can only get the stride when we lock the surface
- QDirectFBPaintDevice* that = const_cast<QDirectFBPaintDevice*>(this);
- that->lockDirectFB();
- Q_ASSERT(that->lockedImage);
- return that->lockedImage->bytesPerLine();
+ if (bpl == -1) {
+ // Can only get the stride when we lock the surface
+ Q_ASSERT(!lockedImage);
+ QDirectFBPaintDevice* that = const_cast<QDirectFBPaintDevice*>(this);
+ that->lockDirectFB();
+ Q_ASSERT(bpl != -1);
+ }
+ return bpl;
}
@@ -121,7 +122,6 @@ QSize QDirectFBPaintDevice::size() const
return QSize(w, h);
}
-
int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
{
if (!dfbSurface)
@@ -130,40 +130,21 @@ int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
int w, h;
dfbSurface->GetSize(dfbSurface, &w, &h);
- int dpmX, dpmY; // Dots-per-meter ;-)
-
- // Do some common calculations:
- switch (metric) {
- case QPaintDevice::PdmWidthMM:
- case QPaintDevice::PdmPhysicalDpiX:
- case QPaintDevice::PdmDpiX:
- dpmX = (screen->deviceWidth() * 1000) / screen->physicalWidth();
- break;
- case QPaintDevice::PdmHeightMM:
- case QPaintDevice::PdmPhysicalDpiY:
- case QPaintDevice::PdmDpiY:
- dpmY = (screen->deviceHeight() * 1000) / screen->physicalHeight();
- break;
- default:
- break;
- }
-
- // Now use those calculations
switch (metric) {
case QPaintDevice::PdmWidth:
return w;
case QPaintDevice::PdmHeight:
return h;
case QPaintDevice::PdmWidthMM:
- return (w * 1000) / dpmX;
+ return (w * 1000) / dotsPerMeterX();
case QPaintDevice::PdmHeightMM:
- return (h * 1000) / dpmY;
+ return (h * 1000) / dotsPerMeterY();
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmDpiX:
- return (dpmX * 254) / 10000; // 0.0254 meters-per-inch
+ return (dotsPerMeterX() * 254) / 10000; // 0.0254 meters-per-inch
case QPaintDevice::PdmPhysicalDpiY:
case QPaintDevice::PdmDpiY:
- return (dpmY * 254) / 10000; // 0.0254 meters-per-inch
+ return (dotsPerMeterY() * 254) / 10000; // 0.0254 meters-per-inch
case QPaintDevice::PdmDepth:
DFBSurfacePixelFormat format;
dfbSurface->GetPixelFormat(dfbSurface, &format);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
index c28d37c..a11064b 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
@@ -54,28 +54,46 @@ QT_MODULE(Gui)
class QDirectFBPaintDevice : public QCustomRasterPaintDevice
{
public:
- QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance())
- : QCustomRasterPaintDevice(0),
- dfbSurface(0),
- lockedImage(0),
- screen(scr) {}
+ ~QDirectFBPaintDevice();
- IDirectFBSurface *directFbSurface() const;
+ IDirectFBSurface *directFBSurface() const;
void lockDirectFB();
void unlockDirectFB();
+ inline bool forceRasterPrimitives() const { return forceRaster; }
+
// Reimplemented from QCustomRasterPaintDevice:
void* memory() const;
QImage::Format format() const;
int bytesPerLine() const;
QSize size() const;
int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
protected:
+ // Shouldn't create QDirectFBPaintDevice by itself but only sub-class it:
+ QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance())
+ : QCustomRasterPaintDevice(0),
+ dfbSurface(0),
+ lockedImage(0),
+ screen(scr),
+ forceRaster(false) {}
+
+ inline int dotsPerMeterX() const
+ {
+ return (screen->deviceWidth() * 1000) / screen->physicalWidth();
+ }
+ inline int dotsPerMeterY() const
+ {
+ return (screen->deviceHeight() * 1000) / screen->physicalHeight();
+ }
+
IDirectFBSurface *dfbSurface;
QImage *lockedImage;
QDirectFBScreen *screen;
+ int bpl;
+ bool forceRaster;
+private:
+ Q_DISABLE_COPY(QDirectFBPaintDevice)
};
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 4fc4035..d9346fd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -61,17 +61,6 @@ static inline uint ALPHA_MUL(uint x, uint a)
return t;
}
-static inline QRect mapRect(const QTransform &transform, const QRect &rect)
-{
- return (transform.isIdentity() ? rect : transform.mapRect(rect));
-}
-
-static inline QRect mapRect(const QTransform &transform, const QRectF &rect)
-{
- return (transform.isIdentity() ? rect : transform.mapRect(rect)).
- toRect();
-}
-
class SurfaceCache
{
public:
@@ -112,7 +101,7 @@ CachedImage::CachedImage(const QImage &image)
description = QDirectFBScreen::getSurfaceDescription(image);
QDirectFBScreen* screen = QDirectFBScreen::instance();
- tmpSurface = screen->createDFBSurface(&description);
+ tmpSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!tmpSurface) {
qWarning("CachedImage CreateSurface failed!");
return;
@@ -124,7 +113,7 @@ CachedImage::CachedImage(const QImage &image)
description.flags = DFBSurfaceDescriptionFlags(description.flags & ~DSDESC_PREALLOCATED);
- s = screen->createDFBSurface(&description);
+ s = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!s)
qWarning("QDirectFBPaintEngine failed caching image");
@@ -159,7 +148,7 @@ IDirectFBSurface* SurfaceCache::getSurface(const uint *buf, int size)
DFBSurfaceDescription description;
description = QDirectFBScreen::getSurfaceDescription(buf, size);
- surface = QDirectFBScreen::instance()->createDFBSurface(&description);
+ surface = QDirectFBScreen::instance()->createDFBSurface(&description, QDirectFBScreen::TrackSurface);
if (!surface)
qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface");
@@ -195,6 +184,7 @@ public:
QBrush brush;
bool antialiased;
+ bool forceRasterPrimitives;
bool simplePen;
bool simpleBrush;
@@ -206,12 +196,12 @@ public:
void setPen(const QPen &pen);
void setBrush(const QBrush &brush);
void setCompositionMode(QPainter::CompositionMode mode);
- void setOpacity(const qreal value);
+ void setOpacity(quint8 value);
void setRenderHints(QPainter::RenderHints hints);
- inline void setDFBColor(const QColor &color) const;
+ inline void setDFBColor(const QColor &color);
- inline bool lock();
+ inline void lock();
inline void unlock();
inline bool dfbCanHandleClip(const QRect &rect) const;
@@ -232,43 +222,41 @@ public:
void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap);
void drawImage(const QRectF &dest, const QImage &image, const QRectF &src);
- void updateClip();
- void updateFlags();
+ inline void updateClip();
inline void setClipDirty();
- void systemStateChanged(); //Needed to be notified when system clip changes
+ void systemStateChanged();
void begin(QPaintDevice *device);
void end();
+ void prepareForBlit(bool alpha);
SurfaceCache *surfaceCache;
-
+ QTransform transform;
+ int lastLockedHeight;
private:
-// QRegion rectsToClippedRegion(const QRect *rects, int n) const;
-// QRegion rectsToClippedRegion(const QRectF *rects, int n) const;
-
IDirectFB *fb;
DFBSurfaceDescription fbDescription;
int fbWidth;
int fbHeight;
quint8 opacity;
- QTransform transform;
- quint32 drawFlags;
- quint32 blitFlags;
- quint32 duffFlags;
- bool dirtyFlags;
+ quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode;
+ DFBSurfacePorterDuffRule porterDuffRule;
+
bool dirtyClip;
bool dfbHandledClip;
+ QDirectFBPaintDevice *dfbDevice;
QDirectFBPaintEngine *q;
};
QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
- : surface(0), antialiased(false), simplePen(false),
- simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1),
- opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true),
- dfbHandledClip(false), q(p)
+ : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false),
+ simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1),
+ fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0),
+ blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true),
+ dfbHandledClip(false), dfbDevice(0), q(p)
{
fb = QDirectFBScreen::instance()->dfb();
surfaceCache = new SurfaceCache;
@@ -279,7 +267,6 @@ QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p
QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate()
{
- unlock();
delete surfaceCache;
}
@@ -305,27 +292,20 @@ void QDirectFBPaintEnginePrivate::setClipDirty()
dirtyClip = true;
}
-
-bool QDirectFBPaintEnginePrivate::lock()
+void QDirectFBPaintEnginePrivate::lock()
{
// We will potentially get a new pointer to the buffer after a
// lock so we need to call the base implementation of prepare so
// it updates its rasterBuffer to point to the new buffer address.
- if (device->devType() == QInternal::CustomRaster) {
- prepare(static_cast<QCustomRasterPaintDevice*>(device));
- return true;
- }
- return false;
+ lastLockedHeight = dfbDevice->height();
+
+ Q_ASSERT(dfbDevice);
+ prepare(dfbDevice);
}
void QDirectFBPaintEnginePrivate::unlock()
{
- QPaintDevice *device = q->paintDevice();
- if (!device) //XXX This should probably be an assert
- return;
-
- Q_ASSERT(device->devType() == QInternal::CustomRaster);
- QDirectFBPaintDevice* dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
+ Q_ASSERT(dfbDevice);
dfbDevice->unlockDirectFB();
}
@@ -338,35 +318,31 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m)
void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
{
- QDirectFBPaintDevice* dfbDevice = 0;
-
+ lastLockedHeight = -1;
if (device->devType() == QInternal::CustomRaster)
dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
else if (device->devType() == QInternal::Pixmap) {
QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
- if (data->classId() == QPixmapData::DirectFBClass) {
- QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
- dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
- }
+ Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
+ QDirectFBPixmapData* dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
+ dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
}
if (dfbDevice)
- surface = dfbDevice->directFbSurface();
+ surface = dfbDevice->directFBSurface();
if (!surface) {
qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
device->devType());
}
+ forceRasterPrimitives = dfbDevice->forceRasterPrimitives();
surface->GetSize(surface, &fbWidth, &fbHeight);
setTransform(QTransform());
antialiased = false;
- drawFlags = DSDRAW_BLEND;
- blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
- duffFlags = DSPD_SRC_OVER;
opacity = 255;
- dirtyFlags = true;
+ setCompositionMode(q->state()->compositionMode());
dirtyClip = true;
setPen(q->state()->pen);
setDFBColor(pen.color());
@@ -374,6 +350,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device)
void QDirectFBPaintEnginePrivate::end()
{
+ dfbDevice = 0;
surface->ReleaseSource(surface);
surface->SetClip(surface, NULL);
surface = 0;
@@ -383,13 +360,14 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p)
{
pen = p;
simplePen = (pen.style() == Qt::NoPen) ||
- (pen.style() == Qt::SolidLine && !antialiased
+ (pen.style() == Qt::SolidLine
+ && !antialiased
+ && (pen.brush().style() == Qt::SolidPattern)
&& (pen.widthF() <= 1 && !matrixScale));
}
void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b)
{
- // TODO: accelerate texture pattern
brush = b;
simpleBrush = (brush.style() == Qt::NoBrush) ||
(brush.style() == Qt::SolidPattern && !antialiased);
@@ -397,91 +375,72 @@ void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b)
void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode)
{
- drawFlags &= ~(DSDRAW_XOR);
- blitFlags &= ~(DSBLIT_XOR);
-
- // TODO: check these mappings!!!!
- quint32 duff = DSPD_NONE;
- quint32 blit = blitFlags;
+ blitFlagsFromCompositionMode = DSBLIT_NOFX;
+ drawFlagsFromCompositionMode = DSDRAW_NOFX;
+ bool blend = true;
switch (mode) {
case QPainter::CompositionMode_SourceOver:
- duff = DSPD_SRC_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_OVER;
break;
case QPainter::CompositionMode_DestinationOver:
- duff = DSPD_DST_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_DST_OVER;
break;
case QPainter::CompositionMode_Clear:
- duff = DSPD_CLEAR;
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_CLEAR;
+ blend = false;
break;
case QPainter::CompositionMode_Source:
- duff = DSPD_SRC;
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC;
+ blend = false;
break;
case QPainter::CompositionMode_Destination:
- blit &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_NONE; // ### need to double check this
+ blend = false;
return;
case QPainter::CompositionMode_SourceIn:
- duff = DSPD_SRC_IN;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_IN;
break;
case QPainter::CompositionMode_DestinationIn:
- duff = DSPD_DST_IN;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_DST_IN;
break;
case QPainter::CompositionMode_SourceOut:
- duff = DSPD_SRC_OUT;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
+ porterDuffRule = DSPD_SRC_OUT;
break;
case QPainter::CompositionMode_DestinationOut:
- duff = DSPD_DST_OUT;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- break;
- case QPainter::CompositionMode_SourceAtop:
- duff = DSPD_SRC_OVER;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- duff = DSPD_DST_OVER;
+ porterDuffRule = DSPD_DST_OUT;
break;
case QPainter::CompositionMode_Xor:
- duff = DSPD_NONE;
- blit |= DSBLIT_BLEND_ALPHACHANNEL;
- drawFlags |= DSDRAW_XOR;
- blit |= DSBLIT_XOR;
- dirtyFlags = true;
+ porterDuffRule = DSPD_XOR;
+ blitFlagsFromCompositionMode |= DSBLIT_XOR;
+ drawFlagsFromCompositionMode |= DSDRAW_XOR;
break;
+// case QPainter::CompositionMode_Plus: // ???
+// porterDuffRule = DSPD_ADD;
+// break;
default:
qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): "
"mode %d not implemented", mode);
- break;
+ return;
}
-
- if (duff != duffFlags || blit != blitFlags) {
- duffFlags = duff;
- blitFlags = blit;
- dirtyFlags = true;
+ // intentially not comparing with current porterDuffRule. surface might have changed.
+ if (blend) {
+ blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL;
+ drawFlagsFromCompositionMode |= DSDRAW_BLEND;
+ }
+ if (opacity != 255) {
+ setOpacity(opacity);
}
}
-void QDirectFBPaintEnginePrivate::setOpacity(const qreal value)
+void QDirectFBPaintEnginePrivate::setOpacity(quint8 op)
{
- const bool wasOpaque = (opacity == 255);
- opacity = quint8(value * 255);
- const bool opaque = (opacity == 255);
-
- if (opaque == wasOpaque)
- return;
-
- if (opaque)
- blitFlags &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR);
- else
- blitFlags |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR);
-
- dirtyFlags = true;
+ opacity = op;
+ if (opacity == 255) {
+ blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA;
+ } else {
+ blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA;
+ }
}
void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
@@ -493,133 +452,83 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
}
}
-void QDirectFBPaintEnginePrivate::updateFlags()
+void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha)
{
- if (!dirtyFlags)
- return;
- surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawFlags));
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
- surface->SetPorterDuff(surface, DFBSurfacePorterDuffRule(duffFlags));
- dirtyFlags = false;
+ quint32 blittingFlags = blitFlagsFromCompositionMode;
+ if (alpha) {
+ surface->SetPorterDuff(surface,
+ (blittingFlags & DSBLIT_BLEND_COLORALPHA)
+ ? DSPD_NONE
+ : porterDuffRule);
+ } else {
+ blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL;
+ surface->SetPorterDuff(surface, DSPD_NONE);
+ }
+ surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
+ surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags));
}
-void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) const
+void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color)
{
+ Q_ASSERT(surface);
const quint8 alpha = (opacity == 255 ?
color.alpha() : ALPHA_MUL(color.alpha(), opacity));
surface->SetColor(surface,
color.red(), color.green(), color.blue(), alpha);
+ quint32 drawingFlags = drawFlagsFromCompositionMode;
+ if (alpha == 255) {
+ drawingFlags &= ~DSDRAW_BLEND;
+ }
+ surface->SetPorterDuff(surface, DSPD_NONE);
+ // PorterDuff messes up alpha values for primitives
+ surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags));
}
void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const
{
- QVarLengthArray<DFBRegion> regions(n);
-
for (int i = 0; i < n; ++i) {
const QLine l = transform.map(lines[i]);
-
- // TODO: clip!
-
- regions[i].x1 = l.x1();
- regions[i].y1 = l.y1();
- regions[i].x2 = l.x2();
- regions[i].y2 = l.y2();
+ surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
}
- surface->DrawLines(surface, regions.data(), n);
}
void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const
{
- QVarLengthArray<DFBRegion> regions(n);
-
for (int i = 0; i < n; ++i) {
const QLine l = transform.map(lines[i]).toLine();
-
- // TODO: clip!
-
- regions[i].x1 = l.x1();
- regions[i].y1 = l.y1();
- regions[i].x2 = l.x2();
- regions[i].y2 = l.y2();
- }
- surface->DrawLines(surface, regions.data(), n);
-}
-
-/* ### Commented out until it can be implemented properly using raster's QClipData
-QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects,
- int n) const
-{
- QRegion region;
-
- for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- region += clip & r;
- }
-
- return region;
-}
-
-QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects,
- int n) const
-{
- QRegion region;
-
- for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- region += clip & r;
+ surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
}
-
- return region;
}
-*/
void QDirectFBPaintEnginePrivate::fillRegion(const QRegion &region) const
{
const QVector<QRect> rects = region.rects();
const int n = rects.size();
- QVarLengthArray<DFBRectangle> dfbRects(n);
-
- for (int i = 0; i < n; ++i) {
- const QRect r = rects.at(i);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
-
- }
- surface->FillRectangles(surface, dfbRects.data(), n);
+ fillRects(rects.constData(), n);
}
void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const
{
- QVarLengthArray<DFBRectangle> dfbRects(n);
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ const QRect r = transform.mapRect(rects[i]);
+ surface->FillRectangle(surface, r.x(), r.y(),
+ r.width(), r.height());
}
- surface->FillRectangles(surface, dfbRects.data(), n);
}
void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const
{
- QVarLengthArray<DFBRectangle> dfbRects(n);
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ const QRect r = transform.mapRect(rects[i]).toRect();
+ surface->FillRectangle(surface, r.x(), r.y(),
+ r.width(), r.height());
}
- surface->FillRectangles(surface, dfbRects.data(), n);
}
void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const
{
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
+ const QRect r = transform.mapRect(rects[i]);
surface->DrawRectangle(surface, r.x(), r.y(),
r.width() + 1, r.height() + 1);
}
@@ -628,7 +537,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const
void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) const
{
for (int i = 0; i < n; ++i) {
- const QRect r = ::mapRect(transform, rects[i]);
+ const QRect r = transform.mapRect(rects[i]).toRect();
surface->DrawRectangle(surface, r.x(), r.y(),
r.width() + 1, r.height() + 1);
}
@@ -638,21 +547,13 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest,
const QPixmap &pixmap,
const QRectF &src)
{
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !pixmap.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
-
+ prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- IDirectFBSurface *s = dfbData->directFbSurface();
+ IDirectFBSurface *s = dfbData->directFBSurface();
const QRect sr = src.toRect();
- const QRect dr = ::mapRect(transform, dest);
+ const QRect dr = transform.mapRect(dest).toRect();
const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
DFBResult result;
@@ -664,27 +565,17 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest,
}
if (result != DFB_OK)
DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
}
void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
const QPixmap &pixmap)
{
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !pixmap.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
-
+ prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- IDirectFBSurface *s = dfbData->directFbSurface();
- const QRect dr = ::mapRect(transform, dest);
+ IDirectFBSurface *s = dfbData->directFBSurface();
+ const QRect dr = transform.mapRect(dest).toRect();
DFBResult result = DFB_OK;
if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) {
@@ -706,7 +597,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
result = surface->BatchBlit(surface, s, rects.constData(),
points.constData(), points.size());
} else {
- const QRect sr = ::mapRect(transform, QRect(0, 0, pixmap.width(), pixmap.height()));
+ const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height()));
const int dx = sr.width();
const int dy = sr.height();
const DFBRectangle sRect = { 0, 0, dx, dy };
@@ -725,25 +616,13 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
if (result != DFB_OK)
DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result);
-
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
}
void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
- const QImage &srcImage,
+ const QImage &image,
const QRectF &src)
{
- QImage image = srcImage;
- if (QDirectFBScreen::getSurfacePixelFormat(image) == DSPF_UNKNOWN) {
- QImage::Format format;
- if (image.hasAlphaChannel())
- format = QImage::Format_ARGB32_Premultiplied;
- else
- format = QImage::Format_RGB32;
- image = image.convertToFormat(format);
- }
-
+ Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN);
CachedImage *img = imageCache[image.cacheKey()];
IDirectFBSurface *imgSurface = 0;
bool doRelease = false;
@@ -767,7 +646,8 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
DFBSurfaceDescription description;
description = QDirectFBScreen::getSurfaceDescription(image);
- imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description);
+ imgSurface = QDirectFBScreen::instance()->createDFBSurface(&description,
+ QDirectFBScreen::DontTrackSurface);
if (!imgSurface) {
qWarning("QDirectFBPaintEnginePrivate::drawImage");
return;
@@ -781,17 +661,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
}
const QRect sr = src.toRect();
- const QRect dr = ::mapRect(transform, dest);
+ const QRect dr = transform.mapRect(dest).toRect();
const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
-
- const bool changeFlags = !image.hasAlphaChannel()
- && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL);
- if (changeFlags) {
- quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL;
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags));
- }
+ prepareForBlit(image.hasAlphaChannel());
if (dr.size() == sr.size()) {
surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y());
} else {
@@ -799,10 +672,10 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest,
dr.width(), dr.height() };
surface->StretchBlit(surface, imgSurface, &sRect, &dRect);
}
- if (changeFlags)
- surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags));
- if (doRelease)
- QDirectFBScreen::instance()->releaseDFBSurface(imgSurface);
+ if (doRelease) {
+ surface->ReleaseSource(surface);
+ imgSurface->Release(imgSurface);
+ }
}
void QDirectFBPaintEnginePrivate::updateClip()
@@ -893,8 +766,7 @@ void QDirectFBPaintEngine::brushChanged()
void QDirectFBPaintEngine::opacityChanged()
{
Q_D(QDirectFBPaintEngine);
- d->setOpacity(state()->opacity);
-
+ d->setOpacity(quint8(state()->opacity * 255));
QRasterPaintEngine::opacityChanged();
}
@@ -902,7 +774,6 @@ void QDirectFBPaintEngine::compositionModeChanged()
{
Q_D(QDirectFBPaintEngine);
d->setCompositionMode(state()->compositionMode());
-
QRasterPaintEngine::compositionModeChanged();
}
@@ -928,11 +799,10 @@ void QDirectFBPaintEngine::setState(QPainterState *s)
{
Q_D(QDirectFBPaintEngine);
QRasterPaintEngine::setState(s);
- if (d->surface)
- d->updateClip();
+ d->setClipDirty();
d->setPen(state()->pen);
d->setBrush(state()->brush);
- d->setOpacity(state()->opacity);
+ d->setOpacity(quint8(state()->opacity * 255));
d->setCompositionMode(state()->compositionMode());
d->setTransform(state()->transform());
}
@@ -941,6 +811,9 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
{
Q_D(QDirectFBPaintEngine);
d->setClipDirty();
+ const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2));
+ if (bottom.y() >= d->lastLockedHeight)
+ d->lock();
QRasterPaintEngine::clip(path, op);
}
@@ -948,15 +821,21 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
{
Q_D(QDirectFBPaintEngine);
d->setClipDirty();
+ if (!d->clip()->hasRectClip && d->clip()->enabled) {
+ const QPoint bottom = d->transform.map(QPoint(0, rect.bottom()));
+ if (bottom.y() >= d->lastLockedHeight)
+ d->lock();
+ }
+
QRasterPaintEngine::clip(rect, op);
}
-
void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush
+ || !d->simplePen || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
return;
@@ -965,12 +844,10 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
d->unlock();
if (d->brush != Qt::NoBrush) {
- d->updateFlags();
d->setDFBColor(d->brush.color());
d->fillRects(rects, rectCount);
}
if (d->pen != Qt::NoPen) {
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawRects(rects, rectCount);
}
@@ -980,7 +857,8 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush
+ || !d->simplePen || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
return;
@@ -989,12 +867,10 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->unlock();
if (d->brush != Qt::NoBrush) {
- d->updateFlags();
d->setDFBColor(d->brush.color());
d->fillRects(rects, rectCount);
}
if (d->pen != Qt::NoPen) {
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawRects(rects, rectCount);
}
@@ -1004,7 +880,7 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->simplePen || !d->dfbCanHandleClip()) {
+ if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
@@ -1012,7 +888,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
if (d->pen != Qt::NoPen) {
d->unlock();
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawLines(lines, lineCount);
}
@@ -1022,7 +897,7 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->simplePen || !d->dfbCanHandleClip()) {
+ if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
@@ -1030,7 +905,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (d->pen != Qt::NoPen) {
d->unlock();
- d->updateFlags();
d->setDFBColor(d->pen.color());
d->drawLines(lines, lineCount);
}
@@ -1045,7 +919,8 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
#ifndef QT_NO_DIRECTFB_PREALLOCATED
d->updateClip();
- if (!d->dfbCanHandleClip(r) || d->matrixRotShear)
+ if (!d->dfbCanHandleClip(r) || d->matrixRotShear
+ || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN)
#endif
{
d->lock();
@@ -1055,7 +930,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
#ifndef QT_NO_DIRECTFB_PREALLOCATED
d->unlock();
- d->updateFlags();
d->drawImage(r, image, sr);
#endif
}
@@ -1074,15 +948,12 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
d->lock();
QRasterPaintEngine::drawPixmap(r, pixmap, sr);
- }
- else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) {
+ } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) {
const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
d->lock();
QRasterPaintEngine::drawImage(r, *img, sr);
- }
- else {
+ } else {
d->unlock();
- d->updateFlags();
d->drawPixmap(r, pixmap, sr);
}
}
@@ -1101,18 +972,15 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
d->lock();
QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp);
- }
- else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) {
- QImage* img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
+ } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) {
+ const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer();
+ d->lock();
QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
data->fromImage(*img, Qt::AutoColor);
const QPixmap pix(data);
- d->lock();
QRasterPaintEngine::drawTiledPixmap(r, pix, sp);
- }
- else {
+ } else {
d->unlock();
- d->updateFlags();
d->drawTiledPixmap(r, pixmap);
}
}
@@ -1184,67 +1052,89 @@ void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
QRasterPaintEngine::fill(path, brush);
}
-void QDirectFBPaintEngine::fillRect(const QRectF &r, const QBrush &brush)
+
+void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
{
Q_D(QDirectFBPaintEngine);
- if (brush.style() != Qt::SolidPattern) {
- d->lock();
- QRasterPaintEngine::fillRect(r, brush);
+ d->updateClip();
+ if (d->dfbCanHandleClip(rect) && !d->matrixRotShear) {
+ switch (brush.style()) {
+ case Qt::SolidPattern: {
+ if (d->forceRasterPrimitives)
+ break;
+ d->unlock();
+ d->setDFBColor(brush.color());
+ const QRect r = d->transform.mapRect(rect).toRect();
+ d->surface->FillRectangle(d->surface, r.x(), r.y(),
+ r.width(), r.height());
+ return; }
+ case Qt::TexturePattern:
+ if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) {
+ //could handle certain types of brush.transform() E.g. scale
+ d->unlock();
+ d->drawTiledPixmap(rect, brush.texture());
+ return;
+ }
+ break;
+ default:
+ break;
+ }
}
- else
- fillRect(r, brush.color());
+ d->lock();
+ QRasterPaintEngine::fillRect(rect, brush);
}
void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
- if (!d->dfbCanHandleClip() || d->matrixRotShear) {
+ if (!d->dfbCanHandleClip() || d->matrixRotShear || d->forceRasterPrimitives) {
d->lock();
QRasterPaintEngine::fillRect(rect, color);
} else {
d->unlock();
- d->updateFlags();
d->setDFBColor(color);
- d->fillRects(&rect, 1);
+ const QRect r = d->transform.mapRect(rect).toRect();
+ d->surface->FillRectangle(d->surface, r.x(), r.y(),
+ r.width(), r.height());
}
}
-
-
-
-
-
-
void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count,
uint color)
{
Q_D(QDirectFBPaintEngine);
- color = INV_PREMUL(color);
-
- QVarLengthArray<DFBRegion> lines(count);
- int j = 0;
- for (int i = 0; i < count; ++i) {
- if (spans[i].coverage == 255) {
- lines[j].x1 = spans[i].x;
- lines[j].y1 = spans[i].y;
- lines[j].x2 = spans[i].x + spans[i].len - 1;
- lines[j].y2 = spans[i].y;
- ++j;
- } else {
- DFBSpan span = { spans[i].x, spans[i].len };
- uint c = BYTE_MUL(color, spans[i].coverage);
+ if (d->forceRasterPrimitives) {
+ d->lock();
+ QRasterPaintEngine::drawColorSpans(spans, count, color);
+ } else {
+ color = INV_PREMUL(color);
+
+ QVarLengthArray<DFBRegion> lines(count);
+ int j = 0;
+ for (int i = 0; i < count; ++i) {
+ if (spans[i].coverage == 255) {
+ lines[j].x1 = spans[i].x;
+ lines[j].y1 = spans[i].y;
+ lines[j].x2 = spans[i].x + spans[i].len - 1;
+ lines[j].y2 = spans[i].y;
+ ++j;
+ } else {
+ DFBSpan span = { spans[i].x, spans[i].len };
+ uint c = BYTE_MUL(color, spans[i].coverage);
+ // ### how does this play with setDFBColor
+ d->surface->SetColor(d->surface,
+ qRed(c), qGreen(c), qBlue(c), qAlpha(c));
+ d->surface->FillSpans(d->surface, spans[i].y, &span, 1);
+ }
+ }
+ if (j > 0) {
d->surface->SetColor(d->surface,
- qRed(c), qGreen(c), qBlue(c), qAlpha(c));
- d->surface->FillSpans(d->surface, spans[i].y, &span, 1);
+ qRed(color), qGreen(color), qBlue(color),
+ qAlpha(color));
+ d->surface->DrawLines(d->surface, lines.data(), j);
}
}
- if (j > 0) {
- d->surface->SetColor(d->surface,
- qRed(color), qGreen(color), qBlue(color),
- qAlpha(color));
- d->surface->DrawLines(d->surface, lines.data(), j);
- }
}
void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
@@ -1253,6 +1143,7 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
{
Q_D(QDirectFBPaintEngine);
IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize);
+ // ### how does this play with setDFBColor
src->SetColor(src, 0, 0, 0, const_alpha);
const DFBRectangle rect = { 0, 0, length, 1 };
d->surface->Blit(d->surface, src, &rect, x, y);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 6352652..0a1696a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -51,7 +51,7 @@ static int global_ser_no = 0;
QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType)
: QPixmapData(pixelType, DirectFBClass),
- engine(0)
+ engine(0), format(QImage::Format_Invalid), alpha(false)
{
setSerialNumber(0);
}
@@ -67,81 +67,119 @@ QDirectFBPixmapData::~QDirectFBPixmapData()
void QDirectFBPixmapData::resize(int width, int height)
{
if (width <= 0 || height <= 0) {
- setSerialNumber(0);
+ invalidate();
return;
}
- DFBSurfaceDescription description;
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH |
- DSDESC_HEIGHT);
- description.width = width;
- description.height = height;
-
- dfbSurface = screen->createDFBSurface(&description);
- if (!dfbSurface)
- qCritical("QDirectFBPixmapData::resize(): Unable to allocate surface");
+ format = screen->pixelFormat();
+ dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height),
+ format,
+ QDirectFBScreen::TrackSurface);
+ alpha = false;
+ forceRaster = (format == QImage::Format_RGB32);
+ if (!dfbSurface) {
+ invalidate();
+ qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
+ return;
+ }
setSerialNumber(++global_ser_no);
}
-void QDirectFBPixmapData::fromImage(const QImage &img,
- Qt::ImageConversionFlags)
-{
- QImage image;
- if (QDirectFBScreen::getSurfacePixelFormat(img) == DSPF_UNKNOWN)
- image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else
- image = img;
- DFBSurfaceDescription description;
- description = QDirectFBScreen::getSurfaceDescription(image);
+// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels)
+static bool checkForAlphaPixels(const QImage &img)
+{
+ const uchar *bits = img.bits();
+ const int bytes_per_line = img.bytesPerLine();
+ const uchar *end_bits = bits + bytes_per_line;
+ const int width = img.width();
+ const int height = img.height();
+ switch (img.format()) {
+ case QImage::Format_Indexed8:
+ return img.hasAlphaChannel();
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ for (int x=0; x<width; ++x) {
+ if ((((uint *)bits)[x] & 0xff000000) != 0xff000000) {
+ return true;
+ }
+ }
+ bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if (bits[0] != 0) {
+ return true;
+ }
+ bits += 3;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB6666_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if ((bits[0] & 0xfc) != 0) {
+ return true;
+ }
+ bits += 3;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
+
+ case QImage::Format_ARGB4444_Premultiplied:
+ for (int y=0; y<height; ++y) {
+ while (bits < end_bits) {
+ if ((bits[0] & 0xf0) != 0) {
+ return true;
+ }
+ bits += 2;
+ }
+ bits = end_bits;
+ end_bits += bytes_per_line;
+ }
+ break;
-#ifndef QT_NO_DIRECTFB_PREALLOCATED
- IDirectFBSurface *imgSurface;
- imgSurface = screen->createDFBSurface(&description);
- if (!imgSurface) {
- qWarning("QDirectFBPixmapData::fromImage()");
- setSerialNumber(0);
- return;
+ default:
+ break;
}
-#ifndef QT_NO_DIRECTFB_PALETTE
- QDirectFBScreen::setSurfaceColorTable(imgSurface, image);
-#endif
-#endif // QT_NO_DIRECTFB_PREALLOCATED
- description.flags = DFBSurfaceDescriptionFlags(description.flags
- & ~DSDESC_PREALLOCATED);
- dfbSurface = screen->createDFBSurface(&description);
+ return false;
+}
+
+void QDirectFBPixmapData::fromImage(const QImage &img,
+ Qt::ImageConversionFlags flags)
+{
+ Q_ASSERT(img.depth() != 1); // these should be handled by QRasterPixmapData
+ if (img.hasAlphaChannel()
+#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
+ && (flags & Qt::NoOpaqueDetection || ::checkForAlphaPixels(img))
+#endif
+ ) {
+ alpha = true;
+ format = screen->alphaPixmapFormat();
+ } else {
+ alpha = false;
+ format = screen->pixelFormat();
+ }
+ dfbSurface = screen->copyToDFBSurface(img, format,
+ QDirectFBScreen::TrackSurface);
+ forceRaster = (format == QImage::Format_RGB32);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::fromImage()");
- setSerialNumber(0);
+ invalidate();
return;
}
-
-#ifndef QT_NO_DIRECTFB_PALETTE
- QDirectFBScreen::setSurfaceColorTable(dfbSurface, image);
-#endif
-
-#ifdef QT_NO_DIRECTFB_PREALLOCATED
- char *mem;
- surface->Lock(surface, DSLF_WRITE, (void**)&mem, &bpl);
- const int w = image.width() * image.depth() / 8;
- for (int i = 0; i < image.height(); ++i) {
- memcpy(mem, image.scanLine(i), w);
- mem += bpl;
- }
- surface->Unlock(surface);
-#else
- DFBResult result;
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0);
- if (result != DFB_OK)
- DirectFBError("QDirectFBPixmapData::fromImage()", result);
- dfbSurface->Flip(dfbSurface, 0, DSFLIP_NONE);
- dfbSurface->ReleaseSource(dfbSurface);
- screen->releaseDFBSurface(imgSurface);
-#endif // QT_NO_DIRECTFB_PREALLOCATED
-
setSerialNumber(++global_ser_no);
}
@@ -152,43 +190,55 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
return;
}
- IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFbSurface();
+ IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFBSurface();
+ const bool hasAlpha = data->hasAlphaChannel();
+ format = (hasAlpha
+ ? QDirectFBScreen::instance()->alphaPixmapFormat()
+ : QDirectFBScreen::instance()->pixelFormat());
- DFBSurfaceDescription description;
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH |
- DSDESC_HEIGHT |
- DSDESC_PIXELFORMAT);
- description.width = rect.width();
- description.height = rect.height();
- src->GetPixelFormat(src, &description.pixelformat);
-
- dfbSurface = screen->createDFBSurface(&description);
+ dfbSurface = screen->createDFBSurface(rect.size(), format,
+ QDirectFBScreen::TrackSurface);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::copy()");
- setSerialNumber(0);
+ invalidate();
return;
}
+ forceRaster = (format == QImage::Format_RGB32);
- DFBResult result;
-#ifndef QT_NO_DIRECTFB_PALETTE
- IDirectFBPalette *palette;
- result = src->GetPalette(src, &palette);
- if (result == DFB_OK) {
- dfbSurface->SetPalette(dfbSurface, palette);
- palette->Release(palette);
+ if (hasAlpha) {
+ dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
+ dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
+ } else {
+ dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
}
-#endif
-
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
const DFBRectangle blitRect = { rect.x(), rect.y(),
rect.width(), rect.height() };
- result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
- if (result != DFB_OK)
+ DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
+ dfbSurface->ReleaseSource(dfbSurface);
+ if (result != DFB_OK) {
DirectFBError("QDirectFBPixmapData::copy()", result);
+ invalidate();
+ return;
+ }
setSerialNumber(++global_ser_no);
}
+static inline bool isOpaqueFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB32:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB666:
+ case QImage::Format_RGB555:
+ case QImage::Format_RGB888:
+ case QImage::Format_RGB444:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
void QDirectFBPixmapData::fill(const QColor &color)
{
@@ -197,72 +247,39 @@ void QDirectFBPixmapData::fill(const QColor &color)
Q_ASSERT(dfbSurface);
- if (color.alpha() < 255 && !hasAlphaChannel()) {
- // convert to surface supporting alpha channel
- DFBSurfacePixelFormat format;
- dfbSurface->GetPixelFormat(dfbSurface, &format);
- switch (format) {
- case DSPF_YUY2:
- case DSPF_UYVY:
- format = DSPF_AYUV;
- break;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB444:
- format = DSPF_ARGB4444;
- break;
- case DSPF_RGB555:
-#endif
- case DSPF_RGB18:
- format = DSPF_ARGB6666;
- break;
- default:
- format = DSPF_ARGB;
- break;
- }
+ alpha = (color.alpha() < 255);
- DFBSurfaceDescription description;
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH |
- DSDESC_HEIGHT |
- DSDESC_PIXELFORMAT);
- dfbSurface->GetSize(dfbSurface, &description.width, &description.height);
- description.pixelformat = format;
- screen->releaseDFBSurface(dfbSurface); // release old surface
-
- dfbSurface = screen->createDFBSurface(&description);
+ if (alpha && ::isOpaqueFormat(format)) {
+ QSize size;
+ dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
+ screen->releaseDFBSurface(dfbSurface);
+ format = screen->alphaPixmapFormat();
+ dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
+ forceRaster = false;
+ setSerialNumber(++global_ser_no);
if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fill()");
- setSerialNumber(0);
+ qWarning("QDirecttFBPixmapData::fill()");
+ invalidate();
return;
}
}
- dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(),
- color.alpha());
-}
-
-bool QDirectFBPixmapData::hasAlphaChannel() const
-{
- if (!serialNumber())
- return false;
-
- DFBSurfacePixelFormat format;
- dfbSurface->GetPixelFormat(dfbSurface, &format);
- switch (format) {
- case DSPF_ARGB1555:
- case DSPF_ARGB:
- case DSPF_LUT8:
- case DSPF_AiRGB:
- case DSPF_A1:
- case DSPF_ARGB2554:
- case DSPF_ARGB4444:
- case DSPF_AYUV:
- case DSPF_A4:
- case DSPF_ARGB1666:
- case DSPF_ARGB6666:
- case DSPF_LUT2:
- return true;
- default:
- return false;
+ if (forceRaster) {
+ // in DSPF_RGB32 all dfb drawing causes the Alpha byte to be
+ // set to 0. This causes issues for the raster engine.
+ char *mem;
+ int bpl;
+ const int h = QPixmapData::height();
+ dfbSurface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl);
+ const int c = color.rgba();
+ for (int i = 0; i < h; ++i) {
+ memset(mem, c, bpl);
+ mem += bpl;
+ }
+ dfbSurface->Unlock(dfbSurface);
+ } else {
+ dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(),
+ color.alpha());
}
}
@@ -274,14 +291,12 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
{
QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
const QImage *image = that->buffer();
- if (image) { // avoid deep copy
- const QImage transformed = image->transformed(transform, mode);
- that->unlockDirectFB();
- QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType());
- data->fromImage(transformed, Qt::AutoColor);
- return QPixmap(data);
- }
- return QPixmapData::transformed(transform, mode);
+ Q_ASSERT(image);
+ const QImage transformed = image->transformed(transform, mode);
+ that->unlockDirectFB();
+ QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
+ data->fromImage(transformed, Qt::AutoColor);
+ return QPixmap(data);
}
int w, h;
@@ -291,15 +306,23 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
if (size.isEmpty())
return QPixmap();
- QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType());
- data->resize(size.width(), size.height());
-
- IDirectFBSurface *dest = data->dfbSurface;
- dest->SetBlittingFlags(dest, DSBLIT_NOFX);
+ QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType);
+ DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
+ data->alpha = alpha;
+ if (alpha) {
+ flags = DSBLIT_BLEND_ALPHACHANNEL;
+ }
+ data->dfbSurface = screen->createDFBSurface(size,
+ format,
+ QDirectFBScreen::TrackSurface);
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
+ data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
+ }
+ data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);
- const DFBRectangle srcRect = { 0, 0, w, h };
const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
- dest->StretchBlit(dest, dfbSurface, &srcRect, &destRect);
+ data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
+ data->dfbSurface->ReleaseSource(data->dfbSurface);
return QPixmap(data);
}
@@ -309,39 +332,25 @@ QImage QDirectFBPixmapData::toImage() const
if (!dfbSurface)
return QImage();
-#ifdef QT_NO_DIRECTFB_PREALLOCATED
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
- const QImage *img = that->buffer();
- const QImage copied = img->copy();
- that->unlockDirectFB();
- return copied;
-#else
-
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
-
- // Always convert to ARGB32:
- QImage image(w, h, QImage::Format_ARGB32);
-
- DFBSurfaceDescription description;
- description = QDirectFBScreen::getSurfaceDescription(image);
-
- IDirectFBSurface *imgSurface = screen->createDFBSurface(&description);
- if (!imgSurface) {
- qWarning("QDirectFBPixmapData::toImage()");
- return QImage();
- }
-
- imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
- DFBResult result = imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::toImage() blit failed", result);
- return QImage();
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
+ QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface));
+ if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
+ if (hasAlphaChannel()) {
+ imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
+ imgSurface->Clear(imgSurface, 0, 0, 0, 0);
+ } else {
+ imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
+ }
+ imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
+ imgSurface->ReleaseSource(imgSurface);
+ imgSurface->Release(imgSurface);
+ return ret;
}
- screen->releaseDFBSurface(imgSurface);
+#endif
- return image;
-#endif // QT_NO_DIRECTFB_PREALLOCATED
+ QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
+ const QImage *img = that->buffer();
+ return img->copy();
}
QPaintEngine* QDirectFBPixmapData::paintEngine() const
@@ -361,3 +370,10 @@ QImage* QDirectFBPixmapData::buffer()
lockDirectFB();
return lockedImage;
}
+
+void QDirectFBPixmapData::invalidate()
+{
+ setSerialNumber(0);
+ alpha = false;
+ format = QImage::Format_Invalid;
+}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
index 32676f8..6cfafcd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
@@ -64,7 +64,7 @@ public:
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
void copy(const QPixmapData *data, const QRect &rect);
void fill(const QColor &color);
- bool hasAlphaChannel() const;
+ inline bool hasAlphaChannel() const { return alpha; }
QPixmap transformed(const QTransform &matrix,
Qt::TransformationMode mode) const;
QImage toImage() const;
@@ -73,9 +73,12 @@ public:
// Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice
int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);}
-
+ inline QImage::Format pixelFormat() const { return format; }
private:
+ void invalidate();
QDirectFBPaintEngine *engine;
+ QImage::Format format;
+ bool alpha;
};
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 3249e65..041d522 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -81,13 +81,15 @@ public:
QDirectFBKeyboardHandler *keyboard;
#endif
bool videoonly;
+ QImage::Format alphaPixmapFormat;
};
QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen)
- : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_BLIT)
+ : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE)
#ifndef QT_NO_DIRECTFB_LAYER
, dfbLayer(0)
#endif
+ , dfbScreen(0)
#ifndef QT_NO_DIRECTFB_MOUSE
, mouse(0)
#endif
@@ -95,6 +97,7 @@ QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen)
, keyboard(0)
#endif
, videoonly(false)
+ , alphaPixmapFormat(QImage::Format_Invalid)
{
#ifndef QT_NO_QWS_SIGNALHANDLER
QWSSignalHandler::instance()->addObject(this);
@@ -129,7 +132,88 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate()
dfb->Release(dfb);
}
-IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription* desc, bool track)
+
+
+// creates a preallocated surface with the same format as the image if
+// possible.
+
+IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options)
+{
+ if (img.isNull()) // assert?
+ return 0;
+ if (QDirectFBScreen::getSurfacePixelFormat(img.format()) == DSPF_UNKNOWN) {
+ QImage image = img.convertToFormat(img.hasAlphaChannel()
+ ? d_ptr->alphaPixmapFormat
+ : pixelFormat());
+ IDirectFBSurface *tmp = createDFBSurface(image, false);
+ if (!tmp) {
+ qWarning("Couldn't create surface createDFBSurface(QImage, bool)");
+ return 0;
+ }
+ IDirectFBSurface *surface = copyDFBSurface(tmp, image.format(), options);
+ tmp->Release(tmp);
+ return surface;
+ }
+
+ DFBSurfaceDescription desc = QDirectFBScreen::getSurfaceDescription(img);
+ IDirectFBSurface *surface = createDFBSurface(&desc, options);
+#ifdef QT_NO_DIRECTFB_PREALLOCATED
+ if (surface) {
+ char *mem;
+ int bpl;
+ surface->Lock(surface, DSLF_WRITE, (void**)&mem, &bpl);
+ const int h = img.height();
+ for (int i = 0; i < h; ++i) {
+ memcpy(mem, img.scanLine(i), bpl);
+ mem += bpl;
+ }
+ surface->Unlock(surface);
+ }
+#endif
+#ifndef QT_NO_DIRECTFB_PALETTE
+ if (img.numColors() != 0 && surface)
+ QDirectFBScreen::setSurfaceColorTable(surface, img);
+#endif
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src,
+ QImage::Format format,
+ SurfaceCreationOptions options)
+{
+ Q_ASSERT(src);
+ QSize size;
+ src->GetSize(src, &size.rwidth(), &size.rheight());
+ IDirectFBSurface *surface = createDFBSurface(size, format, options);
+ DFBSurfacePixelFormat dspf;
+ src->GetPixelFormat(src, &dspf);
+ DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlpha(dspf)
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : DSBLIT_NOFX;
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL)
+ surface->Clear(surface, 0, 0, 0, 0);
+
+ surface->SetBlittingFlags(surface, flags);
+ surface->Blit(surface, src, 0, 0, 0);
+ surface->ReleaseSource(surface);
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size,
+ QImage::Format format,
+ SurfaceCreationOptions options)
+{
+ DFBSurfaceDescription desc;
+ desc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH|DSDESC_HEIGHT);
+ if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format))
+ return 0;
+ desc.width = size.width();
+ desc.height = size.height();
+ return createDFBSurface(&desc, options);
+}
+
+
+IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription *desc, SurfaceCreationOptions options)
{
DFBResult result;
IDirectFBSurface* newSurface = 0;
@@ -142,22 +226,43 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription*
if (d_ptr->videoonly && !(desc->flags & DSDESC_PREALLOCATED)) {
// Add the video only capability. This means the surface will be created in video ram
DFBSurfaceDescription voDesc = *desc;
- voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY);
- voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS);
+ if (!(voDesc.flags & DSDESC_CAPS)) {
+ voDesc.caps = DSCAPS_VIDEOONLY;
+ voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS);
+ } else {
+ voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY);
+ }
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface);
+ if (result != DFB_OK
+#ifdef QT_NO_DEBUG
+ && (desc->flags & DSDESC_CAPS) && (desc->caps & DSCAPS_PRIMARY)
+#endif
+ ) {
+ qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n"
+ " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
+ desc->flags, desc->caps, desc->width, desc->height,
+ desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat),
+ desc->preallocated[0].data, desc->preallocated[0].pitch,
+ DirectFBErrorString(result));
+ }
}
if (!newSurface)
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, desc, &newSurface);
if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::createDFBSurface", result);
+ qWarning("QDirectFBScreen::createDFBSurface() Failed!\n"
+ " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
+ desc->flags, desc->caps, desc->width, desc->height,
+ desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat),
+ desc->preallocated[0].data, desc->preallocated[0].pitch,
+ DirectFBErrorString(result));
return 0;
}
Q_ASSERT(newSurface);
- if (track) {
+ if (options & TrackSurface) {
d_ptr->allocatedSurfaces.insert(newSurface);
//qDebug("Created a new DirectFB surface at %p. New count = %d",
@@ -167,8 +272,67 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription*
return newSurface;
}
-void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface* surface)
+IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img,
+ QImage::Format pixmapFormat,
+ SurfaceCreationOptions options)
+{
+ QImage image = img;
+ if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN
+#ifdef QT_NO_DIRECTFB_PREALLOCATED
+ || image.format() != pixmapFormat
+#endif
+#ifdef QT_NO_DIRECTFB_PALETTE
+ || image.numColors() != 0
+#endif
+ ) {
+ image = image.convertToFormat(pixmapFormat);
+ }
+
+ IDirectFBSurface *dfbSurface = createDFBSurface(image.size(), pixmapFormat, options);
+ if (!dfbSurface) {
+ qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface");
+ return 0;
+ }
+
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
+ IDirectFBSurface *imgSurface = createDFBSurface(image, DontTrackSurface);
+ if (!imgSurface) {
+ qWarning("QDirectFBPixmapData::fromImage()");
+ QDirectFBScreen::releaseDFBSurface(dfbSurface);
+ return 0;
+ }
+
+ Q_ASSERT(imgSurface);
+ DFBSurfaceBlittingFlags flags = img.hasAlphaChannel()
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : DSBLIT_NOFX;
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL)
+ dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
+
+ dfbSurface->SetBlittingFlags(dfbSurface, flags);
+ DFBResult result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0);
+ if (result != DFB_OK)
+ DirectFBError("QDirectFBPixmapData::fromImage()", result);
+ dfbSurface->ReleaseSource(dfbSurface);
+ imgSurface->Release(imgSurface);
+#else // QT_NO_DIRECTFB_PREALLOCATED
+ Q_ASSERT(image.format() == pixmapFormat);
+ char *mem;
+ int bpl;
+ dfbSurface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl);
+ const int w = image.width() * image.depth() / 8;
+ for (int i = 0; i < image.height(); ++i) {
+ memcpy(mem, image.scanLine(i), w);
+ mem += bpl;
+ }
+ dfbSurface->Unlock(dfbSurface);
+#endif
+ return dfbSurface;
+}
+
+void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
{
+ Q_ASSERT(QDirectFBScreen::instance());
Q_ASSERT(surface);
surface->Release(surface);
if (!d_ptr->allocatedSurfaces.remove(surface))
@@ -199,9 +363,9 @@ IDirectFBDisplayLayer* QDirectFBScreen::dfbDisplayLayer()
}
#endif
-DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image)
+DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format)
{
- switch (image.format()) {
+ switch (format) {
#ifndef QT_NO_DIRECTFB_PALETTE
case QImage::Format_Indexed8:
return DSPF_LUT8;
@@ -232,8 +396,11 @@ DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(const QImage &image
};
}
-QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
+QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface)
{
+ DFBSurfacePixelFormat format;
+ surface->GetPixelFormat(surface, &format);
+
switch (format) {
case DSPF_LUT8:
return QImage::Format_Indexed8;
@@ -256,8 +423,14 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
return QImage::Format_RGB666;
case DSPF_RGB32:
return QImage::Format_RGB32;
- case DSPF_ARGB:
- return QImage::Format_ARGB32_Premultiplied;
+ case DSPF_ARGB: {
+ DFBSurfaceCapabilities caps;
+ const DFBResult result = surface->GetCapabilities(surface, &caps);
+ Q_ASSERT(result == DFB_OK);
+ Q_UNUSED(result);
+ return (caps & DSCAPS_PREMULTIPLIED
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_ARGB32); }
default:
break;
}
@@ -267,38 +440,32 @@ QImage::Format QDirectFBScreen::getImageFormat(DFBSurfacePixelFormat format)
DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const QImage &image)
{
DFBSurfaceDescription description;
- DFBSurfacePixelFormat format = getSurfacePixelFormat(image);
+
+ const DFBSurfacePixelFormat format = getSurfacePixelFormat(image.format());
if (format == DSPF_UNKNOWN || image.isNull()) {
description.flags = DFBSurfaceDescriptionFlags(0);
return description;
}
- description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS
- | DSDESC_WIDTH
+ description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH
| DSDESC_HEIGHT
- | DSDESC_PIXELFORMAT
- | DSDESC_PREALLOCATED);
-
- description.caps = DSCAPS_NONE;
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
+ | DSDESC_PREALLOCATED
+#endif
+ | DSDESC_PIXELFORMAT);
+ QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, image.format());
description.width = image.width();
description.height = image.height();
- description.pixelformat = format;
+#ifndef QT_NO_DIRECTFB_PREALLOCATED
description.preallocated[0].data = (void*)(image.bits());
description.preallocated[0].pitch = image.bytesPerLine();
description.preallocated[1].data = 0;
description.preallocated[1].pitch = 0;
+#endif
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB4444_Premultiplied:
+ if (QDirectFBScreen::isPremultiplied(image.format()))
description.caps = DSCAPS_PREMULTIPLIED;
- default:
- break;
- }
return description;
}
@@ -336,7 +503,7 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
if (numColors == 0)
return;
- QVarLengthArray<DFBColor> colors(numColors);
+ QVarLengthArray<DFBColor, 256> colors(numColors);
for (int i = 0; i < numColors; ++i) {
QRgb c = image.color(i);
colors[i].a = qAlpha(c);
@@ -361,50 +528,6 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
palette->Release(palette);
}
-void QDirectFBScreen::setImageColorTable(QImage *image, IDirectFBSurface *surface)
-{
- if (!image || !surface || image->depth() > 8)
- return;
-
- IDirectFBPalette *palette = 0;
- unsigned int numColors = 0;
- DFBResult result;
- do {
- result = surface->GetPalette(surface, &palette);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- result = palette->GetSize(palette, &numColors);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- if (numColors == 0)
- break;
-
- QVarLengthArray<DFBColor> dfbColors(numColors);
- result = palette->GetEntries(palette, dfbColors.data(), numColors, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setImageColorTable GetPalette", result);
- break;
- }
-
- QVector<QRgb> qtColors(numColors);
- for (unsigned int i=0; i<numColors; ++i) {
- const DFBColor &col = dfbColors[i];
- qtColors[i] = qRgba(col.r, col.g, col.b, col.a);
- }
- image->setColorTable(qtColors);
-
- } while (0);
-
- if (palette)
- palette->Release(palette);
-}
-
#endif // QT_NO_DIRECTFB_PALETTE
#if !defined(QT_NO_DIRECTFB_LAYER) && !defined(QT_NO_QWS_CURSOR)
@@ -504,52 +627,43 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
} else if (!image.isNull() && implicitHide) {
show();
}
+ cursor = image.convertToFormat(QDirectFBScreen::instance()->alphaPixmapFormat());
+
+ if (!image.isNull()) {
+ Q_ASSERT(cursor.numColors() == 0);
+ size = cursor.size();
+ hotspot = QPoint(hotx, hoty);
+
+ DFBSurfaceDescription description;
+ description = QDirectFBScreen::getSurfaceDescription(cursor);
+
+ IDirectFBSurface *surface;
+ surface = QDirectFBScreen::instance()->createDFBSurface(&description,
+ QDirectFBScreen::TrackSurface);
+ if (!surface) {
+ qWarning("QDirectFBScreenCursor::set: Unable to create surface");
+ return;
+ }
+ DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: "
+ "Unable to set cooperative level", result);
+ }
+ result = layer->SetCursorShape(layer, surface, hotx, hoty);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to set cursor shape",
+ result);
+ }
-#ifdef QT_NO_DIRECTFB_PALETTE
- if (image.numColors() > 0)
- cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else
-#endif
- if (image.format() == QImage::Format_Indexed8) {
- cursor = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- } else {
- cursor = image;
- }
- size = cursor.size();
- hotspot = QPoint(hotx, hoty);
-
- DFBSurfaceDescription description;
- description = QDirectFBScreen::getSurfaceDescription(cursor);
-
- IDirectFBSurface *surface;
- surface = QDirectFBScreen::instance()->createDFBSurface(&description);
- if (!surface) {
- qWarning("QDirectFBScreenCursor::set: Unable to create surface");
- return;
- }
-#ifndef QT_NO_DIRECTFB_PALETTE
- QDirectFBScreen::setSurfaceColorTable(surface, cursor);
-#endif
-
- DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorShape(layer, surface, hotx, hoty);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to set cursor shape",
- result);
- }
+ result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: "
+ "Unable to reset cooperative level", result);
+ }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: "
- "Unable to reset cooperative level", result);
+ if (surface)
+ QDirectFBScreen::instance()->releaseDFBSurface(surface);
}
-
- if (surface)
- QDirectFBScreen::instance()->releaseDFBSurface(surface);
}
#endif // QT_NO_DIRECTFB_LAYER
@@ -608,7 +722,7 @@ int QDirectFBScreen::depth(DFBSurfacePixelFormat format)
void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
{
- QRegExp flipRegexp(QLatin1String("^flip=([\\w,]+)$"));
+ QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$"));
int index = args.indexOf(flipRegexp);
if (index >= 0) {
const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','),
@@ -627,6 +741,8 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
qWarning("QDirectFBScreen: Unknown flip argument: %s",
qPrintable(flip));
}
+ } else {
+ flipFlags = DFBSurfaceFlipFlags(DSFLIP_BLIT);
}
}
@@ -656,6 +772,18 @@ static void printDirectFBInfo(IDirectFB *fb)
dev.blitting_flags, dev.drawing_flags, dev.video_memory);
}
+static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value)
+{
+ Q_ASSERT(value);
+ QRegExp rx(QString("%1=?(\\d+)").arg(variable));
+ rx.setCaseSensitivity(Qt::CaseInsensitive);
+ if (arguments.indexOf(rx) != -1) {
+ *value = rx.cap(1).toInt();
+ return true;
+ }
+ return false;
+}
+
bool QDirectFBScreen::connect(const QString &displaySpec)
{
DFBResult result = DFB_OK;
@@ -677,7 +805,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
}
const QStringList displayArgs = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
+ QString::SkipEmptyParts);
d_ptr->setFlipFlags(displayArgs);
@@ -701,23 +829,57 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
DFBSurfaceDescription description;
description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS);
+ if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
+ description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_WIDTH);
+ if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
+ description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_HEIGHT);
description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY
| DSCAPS_DOUBLE
| DSCAPS_STATIC_ALLOC);
- if (!(d_ptr->flipFlags & DSFLIP_BLIT)) {
+ if (displayArgs.contains(QLatin1String("forcepremultiplied"),
+ Qt::CaseInsensitive)) {
description.caps = DFBSurfaceCapabilities(description.caps
- | DSCAPS_DOUBLE
- | DSCAPS_TRIPLE);
+ | DSCAPS_PREMULTIPLIED);
}
-
// We don't track the primary surface as it's released in disconnect
- d_ptr->dfbSurface = createDFBSurface(&description, false);
+ d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface);
if (!d_ptr->dfbSurface) {
DirectFBError("QDirectFBScreen: error creating primary surface",
result);
return false;
}
+
+ // Work out what format we're going to use for surfaces with an alpha channel
+ d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(d_ptr->dfbSurface);
+ setPixelFormat(d_ptr->alphaPixmapFormat);
+ switch (d_ptr->alphaPixmapFormat) {
+ case QImage::Format_RGB666:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
+ break;
+ case QImage::Format_RGB444:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied;
+ break;
+ case QImage::NImageFormats:
+ case QImage::Format_Invalid:
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ case QImage::Format_Indexed8:
+ case QImage::Format_RGB32:
+ case QImage::Format_RGB888:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB555:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
+ break;
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB6666_Premultiplied:
+ // works already
+ break;
+ }
d_ptr->dfbSurface->GetSize(d_ptr->dfbSurface, &w, &h);
data = 0;
@@ -733,21 +895,11 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
else
DirectFBError("QDirectFBScreen: error getting surface format", result);
- setPixelFormat(getImageFormat(format));
+ setPixelFormat(getImageFormat(d_ptr->dfbSurface));
physWidth = physHeight = -1;
- QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)"));
- int dimIdxW = displayArgs.indexOf(mmWidthRx);
- if (dimIdxW >= 0) {
- mmWidthRx.exactMatch(displayArgs.at(dimIdxW));
- physWidth = mmWidthRx.cap(1).toInt();
- }
- QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)"));
- int dimIdxH = displayArgs.indexOf(mmHeightRx);
- if (dimIdxH >= 0) {
- mmHeightRx.exactMatch(displayArgs.at(dimIdxH));
- physHeight = mmHeightRx.cap(1).toInt();
- }
+ ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
+ ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
const int dpi = 72;
if (physWidth < 0)
physWidth = qRound(dw * 25.4 / dpi);
@@ -855,19 +1007,21 @@ void QDirectFBScreen::blank(bool on)
QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const
{
#ifdef QT_NO_DIRECTFB_WM
- if (QApplication::type() == QApplication::GuiServer)
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this), widget);
- else
+ if (QApplication::type() == QApplication::GuiServer) {
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
+ } else {
return QScreen::createSurface(widget);
+ }
#else
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this), widget);
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
#endif
}
QWSWindowSurface* QDirectFBScreen::createSurface(const QString &key) const
{
- if (key == QLatin1String("directfb"))
- return new QDirectFBSurface(const_cast<QDirectFBScreen*>(this));
+ if (key == QLatin1String("directfb")) {
+ return new QDirectFBSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
+ }
return QScreen::createSurface(key);
}
@@ -900,7 +1054,7 @@ void QDirectFBScreen::compose(const QRegion &region)
if (surface->key() == QLatin1String("directfb")) {
QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface);
- blit(s->directFbSurface(), offset, r);
+ blit(s->directFBSurface(), offset, r);
} else {
blit(surface->image(), offset, r);
}
@@ -949,11 +1103,12 @@ void QDirectFBScreen::compose(const QRegion &region)
if (surface->key() == QLatin1String("directfb")) {
QDirectFBSurface *s = static_cast<QDirectFBSurface*>(surface);
- blit(s->directFbSurface(), offset, r);
+ blit(s->directFBSurface(), offset, r);
} else {
blit(surface->image(), offset, r);
}
}
+ d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface);
}
// Normally, when using DirectFB to compose the windows (I.e. when
@@ -995,21 +1150,14 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing)
void QDirectFBScreen::blit(const QImage &img, const QPoint &topLeft,
const QRegion &reg)
{
- IDirectFBSurface *src = 0;
- DFBSurfaceDescription description = getSurfaceDescription(img);
-
- src = createDFBSurface(&description);
+ IDirectFBSurface *src = createDFBSurface(img, QDirectFBScreen::DontTrackSurface);
if (!src) {
qWarning("QDirectFBScreen::blit(): Error creating surface");
return;
}
-#ifndef QT_NO_DIRECTFB_PALETTE
- setSurfaceColorTable(d_ptr->dfbSurface, img);
-#endif
-
blit(src, topLeft, reg);
-
- releaseDFBSurface(src);
+ d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface);
+ src->Release(src);
}
void QDirectFBScreen::blit(IDirectFBSurface *src, const QPoint &topLeft,
@@ -1045,20 +1193,51 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
if (region.isEmpty())
return;
- const QVector<QRect> rects = region.rects();
- QVarLengthArray<DFBRectangle> dfbRects(rects.size());
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- dfbRects[i].x = r.x();
- dfbRects[i].y = r.y();
- dfbRects[i].w = r.width();
- dfbRects[i].h = r.height();
+ if (QDirectFBScreen::getImageFormat(d_ptr->dfbSurface) == QImage::Format_RGB32) {
+ uchar *mem;
+ int bpl;
+ d_ptr->dfbSurface->Lock(d_ptr->dfbSurface, DSLF_WRITE, (void**)&mem, &bpl);
+ QImage img(mem, w, h, bpl, QImage::Format_RGB32);
+ QPainter p(&img);
+ p.setBrush(color);
+ p.setPen(Qt::NoPen);
+ const QVector<QRect> rects = region.rects();
+ p.drawRects(rects.constData(), rects.size());
+ p.end();
+ d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface);
+ } else {
+ d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface,
+ color.red(), color.green(), color.blue(),
+ color.alpha());
+ const QVector<QRect> rects = region.rects();
+ for (int i=0; i<rects.size(); ++i) {
+ const QRect &r = rects.at(i);
+ d_ptr->dfbSurface->FillRectangle(d_ptr->dfbSurface,
+ r.x(), r.y(), r.width(), r.height());
+ }
}
+}
- d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface,
- color.red(), color.green(), color.blue(),
- color.alpha());
- d_ptr->dfbSurface->FillRectangles(d_ptr->dfbSurface, dfbRects.data(),
- dfbRects.size());
+QImage::Format QDirectFBScreen::alphaPixmapFormat() const
+{
+ return d_ptr->alphaPixmapFormat;
}
+bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
+ QImage::Format format)
+{
+ const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
+ if (pixelformat == DSPF_UNKNOWN)
+ return false;
+ description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_PIXELFORMAT);
+ description->pixelformat = pixelformat;
+ if (QDirectFBScreen::isPremultiplied(format)) {
+ if (!(description->flags & DSDESC_CAPS)) {
+ description->caps = DSCAPS_PREMULTIPLIED;
+ description->flags = DFBSurfaceDescriptionFlags(description->flags | DSDESC_CAPS);
+ } else {
+ description->caps = DFBSurfaceCapabilities(description->caps | DSCAPS_PREMULTIPLIED);
+ }
+ }
+ return true;
+}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
index e9a2f63..f394ac1 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -88,23 +88,43 @@ public:
#endif
// Track surface creation/release so we can release all on exit
- IDirectFBSurface* createDFBSurface(const DFBSurfaceDescription* desc, bool track = true);
+ enum SurfaceCreationOption {
+ DontTrackSurface = 0,
+ TrackSurface = 1
+ };
+ Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption);
+ IDirectFBSurface *createDFBSurface(const DFBSurfaceDescription *desc,
+ SurfaceCreationOptions options);
+ IDirectFBSurface *createDFBSurface(const QImage &image,
+ SurfaceCreationOptions options);
+ IDirectFBSurface *createDFBSurface(const QSize &size,
+ QImage::Format format,
+ SurfaceCreationOptions options);
+ IDirectFBSurface *copyDFBSurface(IDirectFBSurface *src,
+ QImage::Format format,
+ SurfaceCreationOptions options);
+ IDirectFBSurface *copyToDFBSurface(const QImage &image,
+ QImage::Format format,
+ SurfaceCreationOptions options);
void releaseDFBSurface(IDirectFBSurface* surface);
+
bool preferVideoOnly() const;
static int depth(DFBSurfacePixelFormat format);
- static DFBSurfacePixelFormat getSurfacePixelFormat(const QImage &image);
+ static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format);
static DFBSurfaceDescription getSurfaceDescription(const QImage &image);
static DFBSurfaceDescription getSurfaceDescription(const uint *buffer,
int length);
- static QImage::Format getImageFormat(DFBSurfacePixelFormat format);
+ static QImage::Format getImageFormat(IDirectFBSurface *surface);
+ static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format);
static inline bool isPremultiplied(QImage::Format format);
+ static inline bool hasAlpha(DFBSurfacePixelFormat format);
+ QImage::Format alphaPixmapFormat() const;
#ifndef QT_NO_DIRECTFB_PALETTE
static void setSurfaceColorTable(IDirectFBSurface *surface,
const QImage &image);
- static void setImageColorTable(QImage *image, IDirectFBSurface *surface);
#endif
private:
@@ -115,6 +135,8 @@ private:
QDirectFBScreenPrivate *d_ptr;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions);
+
inline bool QDirectFBScreen::isPremultiplied(QImage::Format format)
{
switch (format) {
@@ -130,6 +152,26 @@ inline bool QDirectFBScreen::isPremultiplied(QImage::Format format)
return false;
}
+inline bool QDirectFBScreen::hasAlpha(DFBSurfacePixelFormat format)
+{
+ switch (format) {
+ case DSPF_ARGB1555:
+ case DSPF_ARGB:
+ case DSPF_LUT8:
+ case DSPF_AiRGB:
+ case DSPF_A1:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_AYUV:
+ case DSPF_A4:
+ case DSPF_ARGB1666:
+ case DSPF_ARGB6666:
+ case DSPF_LUT2:
+ return true;
+ default:
+ return false;
+ }
+}
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
index ab1d0f1..8ed308c 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp
@@ -50,28 +50,38 @@
//#define QT_DIRECTFB_DEBUG_SURFACES 1
-QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr)
+QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen* scr)
: QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
#endif
, engine(0)
+ , flipFlags(flip)
{
setSurfaceFlags(Opaque | Buffered);
+#ifdef QT_DIRECTFB_TIMING
+ frames = 0;
+ timer.start();
+#endif
}
-QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget)
+QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
: QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
#endif
, engine(0)
+ , flipFlags(flip)
{
onscreen = widget->testAttribute(Qt::WA_PaintOnScreen);
if (onscreen)
setSurfaceFlags(Opaque | RegionReserved);
else
setSurfaceFlags(Opaque | Buffered);
+#ifdef QT_DIRECTFB_TIMING
+ frames = 0;
+ timer.start();
+#endif
}
QDirectFBSurface::~QDirectFBSurface()
@@ -86,14 +96,26 @@ bool QDirectFBSurface::isValid() const
#ifndef QT_NO_DIRECTFB_WM
void QDirectFBSurface::createWindow()
{
+#ifdef QT_NO_DIRECTFB_LAYER
+#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM
+#else
IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
if (!layer)
qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
- DFBWindowDescription description;
- description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION |
- DWCAPS_ALPHACHANNEL);
- description.flags = DWDESC_CAPS;
+ DFBWindowDescription description;
+ description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION);
+ description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS
+ |DWDESC_SURFACE_CAPS
+ |DWDESC_PIXELFORMAT);
+
+ description.surface_caps = DSCAPS_NONE;
+ if (screen->preferVideoOnly())
+ description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY);
+ const QImage::Format format = screen->pixelFormat();
+ description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
+ if (QDirectFBScreen::isPremultiplied(format))
+ description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps);
DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
if (result != DFB_OK)
@@ -103,6 +125,8 @@ void QDirectFBSurface::createWindow()
dfbSurface->Release(dfbSurface);
dfbWindow->GetSurface(dfbWindow, &dfbSurface);
+ forceRaster = (format == QImage::Format_RGB32);
+#endif
}
#endif // QT_NO_DIRECTFB_WM
@@ -115,26 +139,32 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask)
dfbWindow = 0;
}
#endif
- if (dfbSurface) {
+ if (dfbSurface && dfbSurface != screen->dfbSurface()) {
dfbSurface->Release(dfbSurface);
dfbSurface = 0;
}
} else if (rect != geometry()) {
- const bool isResize = rect.size() != geometry().size();
DFBResult result = DFB_OK;
// If we're in a resize, the surface shouldn't be locked
- Q_ASSERT( (lockedImage == 0) || (isResize == false));
+ Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size()));
- IDirectFBSurface *s = screen->dfbSurface();
- if (onscreen && s) {
- if (dfbSurface)
+ if (onscreen) {
+ IDirectFBSurface *primarySurface = screen->dfbSurface();
+ Q_ASSERT(primarySurface);
+ if (dfbSurface && dfbSurface != primarySurface)
dfbSurface->Release(dfbSurface);
- DFBRectangle r = { rect.x(), rect.y(),
- rect.width(), rect.height() };
- result = s->GetSubSurface(s, &r, &dfbSurface);
+ if (rect == screen->region().boundingRect()) {
+ dfbSurface = primarySurface;
+ } else {
+ const DFBRectangle r = { rect.x(), rect.y(),
+ rect.width(), rect.height() };
+ result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
+ }
+ forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32);
} else {
+ const bool isResize = rect.size() != geometry().size();
#ifdef QT_NO_DIRECTFB_WM
if (isResize) {
if (dfbSurface)
@@ -152,9 +182,10 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask)
DSDESC_PIXELFORMAT);
description.width = rect.width();
description.height = rect.height();
- description.pixelformat = DSPF_ARGB;
-
- dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false);
+ QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description,
+ screen->pixelFormat());
+ dfbSurface = screen->createDFBSurface(&description, false);
+ forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32);
} else {
Q_ASSERT(dfbSurface);
}
@@ -219,7 +250,7 @@ void QDirectFBSurface::setPermanentState(const QByteArray &state)
bool QDirectFBSurface::scroll(const QRegion &region, int dx, int dy)
{
- if (!dfbSurface)
+ if (!dfbSurface || !(flipFlags & DSFLIP_BLIT))
return false;
const QVector<QRect> rects = region.rects();
@@ -241,7 +272,7 @@ bool QDirectFBSurface::scroll(const QRegion &region, int dx, int dy)
dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
dfbSurface->BatchBlit(dfbSurface, dfbSurface,
dfbRects.data(), dfbPoints.data(), n);
-
+ dfbSurface->ReleaseSource(dfbSurface);
return true;
}
@@ -306,10 +337,15 @@ inline bool isWidgetOpaque(const QWidget *w)
return false;
}
-
void QDirectFBSurface::flush(QWidget *widget, const QRegion &region,
const QPoint &offset)
{
+ Q_UNUSED(widget);
+#ifdef QT_NO_DIRECTFB_WM
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+#endif
+
QWidget *win = window();
// hw: make sure opacity information is updated before compositing
@@ -330,18 +366,41 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion &region,
if (winOpacity != opacity)
dfbWindow->SetOpacity(dfbWindow, winOpacity);
}
+ if (!(flipFlags & DSFLIP_BLIT)) {
+ dfbSurface->Flip(dfbSurface, 0, flipFlags);
+ } else {
+ if (region.numRects() > 1) {
+ const QVector<QRect> rects = region.rects();
+ DFBSurfaceFlipFlags tmpFlags = flipFlags;
+ if (flipFlags & DSFLIP_WAIT)
+ tmpFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT);
+ for (int i=0; i<rects.size(); ++i) {
+ const QRect &r = rects.at(i);
+ const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
+ r.x() + r.width() + offset.x(),
+ r.y() + r.height() + offset.y() };
+ dfbSurface->Flip(dfbSurface, &dfbReg,
+ i + 1 < rects.size()
+ ? tmpFlags
+ : flipFlags);
+ }
+ } else {
+ const QRect r = region.boundingRect();
+ const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
+ r.x() + r.width() + offset.x(),
+ r.y() + r.height() + offset.y() };
+ dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags);
+ }
+ }
#endif
-
- // XXX: have to call the base function first as the decoration is
- // currently painted there
- QWSWindowSurface::flush(widget, region, offset);
-
-#ifndef QT_NO_DIRECTFB_WM
- const QRect br = region.boundingRect().translated(painterOffset());
- const DFBRegion r = { br.x(), br.y(),
- br.x() + br.width(), br.y() + br.height() };
-
- dfbSurface->Flip(dfbSurface, &r, DSFLIP_NONE);
+#ifdef QT_DIRECTFB_TIMING
+ enum { Secs = 3 };
+ ++frames;
+ if (timer.elapsed() >= Secs * 1000) {
+ qDebug("%d fps", int(double(frames) / double(Secs)));
+ frames = 0;
+ timer.restart();
+ }
#endif
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
index a9cdb7d..ab4145d 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h
@@ -50,6 +50,10 @@
#include <private/qwindowsurface_qws_p.h>
#include <directfb.h>
+#ifdef QT_DIRECTFB_TIMING
+#include <qdatetime.h>
+#endif
+
QT_BEGIN_HEADER
QT_MODULE(Gui)
@@ -57,8 +61,8 @@ QT_MODULE(Gui)
class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice
{
public:
- QDirectFBSurface(QDirectFBScreen* scr);
- QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget);
+ QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr);
+ QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget);
~QDirectFBSurface();
bool isValid() const;
@@ -95,6 +99,11 @@ private:
bool onscreen;
QList<QImage*> bufferImages;
+ DFBSurfaceFlipFlags flipFlags;
+#ifdef QT_DIRECTFB_TIMING
+ int frames;
+ QTime timer;
+#endif
};
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README
index b830066..ec02efb 100644
--- a/src/plugins/gfxdrivers/powervr/README
+++ b/src/plugins/gfxdrivers/powervr/README
@@ -8,6 +8,9 @@ is built as two libraries: The actual QScreen plugin used by Qt (in the
pvreglscreen directory) and a WSEGL plugin for the PowerVR drivers (in the
QWSWSEGL directory).
+Qt/Embedded needs to be configured with the QT_QWS_CLIENTBLIT and
+QT_NO_QWS_CURSOR defines.
+
The PowerVR drivers provide the WSEGL plugin API to allow window systems such as
QWS to integrate correctly. In order to use the integration, the WSEGL plugin
(libpvrQWSWSEGL.so, usually installed into the Qt library directory) must be in
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
index 3a94851..b0ffbf1 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
@@ -381,7 +381,7 @@ void PvrEglSurfaceHolder::removeSurface()
// create the temporary surface again.
if (surface == EGL_NO_SURFACE && dpy != EGL_NO_DISPLAY) {
surface = eglCreateWindowSurface
- (dpy, config, (EGLNativeWindowType)tempSurface, NULL);
+ (dpy, config, (EGLNativeWindowType)(-1), NULL);
if (surface == EGL_NO_SURFACE)
qWarning("Could not re-create the temporary EGL surface");
}
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 31e5c66..6d0bc1f 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -809,7 +809,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
if (params.contains(QLatin1String("GetHeaderInformation"))) {
if (!ensureValidImage(outImage, &cinfo, true))
- return false;
+ 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)",
@@ -848,7 +848,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
// Unsupported format
}
if (outImage->isNull())
- return false;
+ longjmp(jerr.setjmp_buffer, 1);
if (!outImage->isNull()) {
QImage tmpImage(cinfo.output_width, 1, QImage::Format_RGB32);
@@ -894,7 +894,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage,
#endif
} else {
if (!ensureValidImage(outImage, &cinfo))
- return false;
+ longjmp(jerr.setjmp_buffer, 1);
uchar* data = outImage->bits();
int bpl = outImage->bytesPerLine();
diff --git a/src/qt3support/itemviews/q3listview.cpp b/src/qt3support/itemviews/q3listview.cpp
index 1ebee42..1effdaa 100644
--- a/src/qt3support/itemviews/q3listview.cpp
+++ b/src/qt3support/itemviews/q3listview.cpp
@@ -3126,7 +3126,8 @@ void Q3ListView::clear()
if (wasUpdatesEnabled)
viewport()->setUpdatesEnabled(false);
setContentsPos(0, 0);
- viewport()->setUpdatesEnabled(wasUpdatesEnabled);
+ if (wasUpdatesEnabled)
+ viewport()->setUpdatesEnabled(true);
bool block = signalsBlocked();
blockSignals(true);
diff --git a/src/qt3support/text/q3richtext.cpp b/src/qt3support/text/q3richtext.cpp
index c058e37..e508001 100644
--- a/src/qt3support/text/q3richtext.cpp
+++ b/src/qt3support/text/q3richtext.cpp
@@ -4895,7 +4895,8 @@ void Q3TextParagraph::drawString(QPainter &painter, const QString &str, int star
bool extendRight = false;
bool extendLeft = false;
bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key()));
- if (selWrap || this->str->at(real_selEnd).lineStart) {
+ if (selWrap
+ || ((real_selEnd < this->str->length()) && this->str->at(real_selEnd).lineStart)) {
extendRight = (fullSelectionWidth != 0);
if (!extendRight && !rightToLeft)
tmpw += painter.fontMetrics().width(QLatin1Char(' '));
diff --git a/src/script/qscriptengine.cpp b/src/script/qscriptengine.cpp
index d4e1923..d8908ed 100644
--- a/src/script/qscriptengine.cpp
+++ b/src/script/qscriptengine.cpp
@@ -1169,7 +1169,8 @@ bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
{
QScriptValueImpl impl = QScriptValuePrivate::valueOf(value);
- return QScriptEnginePrivate::convert(impl, type, ptr, /*engine=*/0);
+ QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(value.engine());
+ return QScriptEnginePrivate::convert(impl, type, ptr, eng_p);
}
/*!
diff --git a/src/scripttools/debugging/qscriptbreakpointswidget.cpp b/src/scripttools/debugging/qscriptbreakpointswidget.cpp
index aea1fe7..efb3047 100644
--- a/src/scripttools/debugging/qscriptbreakpointswidget.cpp
+++ b/src/scripttools/debugging/qscriptbreakpointswidget.cpp
@@ -225,7 +225,6 @@ public:
bool eventFilter(QObject *editor, QEvent *event)
{
-#if QT_VERSION >= 0x040500
if (QLineEdit *le = qobject_cast<QLineEdit*>(editor)) {
if (event->type() == QEvent::KeyPress) {
int key = static_cast<QKeyEvent*>(event)->key();
@@ -237,21 +236,18 @@ public:
}
}
}
-#endif
return QStyledItemDelegate::eventFilter(editor, event);
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
-#if QT_VERSION >= 0x040500
if (index.column() == 2) {
// check that the syntax is OK
QString condition = qobject_cast<QLineEdit*>(editor)->text();
if (QScriptEngine::checkSyntax(condition).state() != QScriptSyntaxCheckResult::Valid)
return;
}
-#endif
QStyledItemDelegate::setModelData(editor, model, index);
}
@@ -261,11 +257,7 @@ private Q_SLOTS:
QWidget *editor = qobject_cast<QWidget*>(sender());
QPalette pal = editor->palette();
QColor col;
-#if QT_VERSION >= 0x040500
bool ok = (QScriptEngine::checkSyntax(text).state() == QScriptSyntaxCheckResult::Valid);
-#else
- bool ok = true;
-#endif
if (ok) {
col = Qt::white;
} else {
diff --git a/src/scripttools/debugging/qscriptcompletiontask.cpp b/src/scripttools/debugging/qscriptcompletiontask.cpp
index 3767505..119b96a 100644
--- a/src/scripttools/debugging/qscriptcompletiontask.cpp
+++ b/src/scripttools/debugging/qscriptcompletiontask.cpp
@@ -162,11 +162,7 @@ void QScriptCompletionTaskPrivate::completeScriptExpression()
obj = ctx->thisObject();
} else {
QScriptValueList scopeChain;
-#if QT_VERSION >= 0x040500
scopeChain = ctx->scopeChain();
-#else
- scopeChain.append(ctx->activationObject());
-#endif
for (int i = 0; i < scopeChain.size(); ++i) {
QScriptValue oo = scopeChain.at(i).property(topLevelIdent);
if (oo.isObject()) {
@@ -180,11 +176,7 @@ void QScriptCompletionTaskPrivate::completeScriptExpression()
if (obj.isValid())
objects.append(obj);
} else {
-#if QT_VERSION >= 0x040500
objects << ctx->scopeChain();
-#else
- objects.append(ctx->activationObject());
-#endif
QStringList keywords;
keywords.append(QString::fromLatin1("this"));
keywords.append(QString::fromLatin1("true"));
diff --git a/src/scripttools/debugging/qscriptdebugger.cpp b/src/scripttools/debugging/qscriptdebugger.cpp
index 5a356ae..ce43572 100644
--- a/src/scripttools/debugging/qscriptdebugger.cpp
+++ b/src/scripttools/debugging/qscriptdebugger.cpp
@@ -663,11 +663,7 @@ QString QScriptDebuggerPrivate::toolTip(int frameIndex, int lineNumber,
objects.append(ctx->thisObject());
++pathIndex;
} else {
-#if QT_VERSION >= 0x040500
objects << ctx->scopeChain();
-#else
- objects.append(ctx->activationObject());
-#endif
}
for (int i = 0; i < objects.size(); ++i) {
QScriptValue val = objects.at(i);
@@ -991,13 +987,11 @@ public:
qint64 scriptId = m_added.at(m_index);
m_debugger->scriptsModel->addScript(scriptId, data);
-#if QT_VERSION >= 0x040500
// ### could be slow, might want to do this in a separate thread
QString xml = qt_scriptToXml(data.contents(), data.baseLineNumber());
QScriptXmlParser::Result extraInfo = QScriptXmlParser::parse(xml);
m_debugger->scriptsModel->addExtraScriptInfo(
scriptId, extraInfo.functionsInfo, extraInfo.executableLineNumbers);
-#endif
if (++m_index < m_added.size())
frontend.scheduleGetScriptData(m_added.at(m_index));
diff --git a/src/scripttools/debugging/qscriptdebuggeragent.cpp b/src/scripttools/debugging/qscriptdebuggeragent.cpp
index fcba033..0ea9c99 100644
--- a/src/scripttools/debugging/qscriptdebuggeragent.cpp
+++ b/src/scripttools/debugging/qscriptdebuggeragent.cpp
@@ -88,16 +88,9 @@ QScriptDebuggerAgentPrivate *QScriptDebuggerAgentPrivate::get(
*/
QScriptDebuggerAgent::QScriptDebuggerAgent(
QScriptDebuggerBackendPrivate *backend, QScriptEngine *engine)
-#if QT_VERSION >= 0x040500
: QScriptEngineAgent(*new QScriptDebuggerAgentPrivate, engine)
-#else
- : QScriptEngineAgent(engine), d_ptr(new QScriptDebuggerAgentPrivate)
-#endif
{
Q_D(QScriptDebuggerAgent);
-#if QT_VERSION < 0x040500
- d_ptr->q_ptr = this;
-#endif
d->backend = backend;
QScriptContext *ctx = engine->currentContext();
@@ -117,9 +110,6 @@ QScriptDebuggerAgent::~QScriptDebuggerAgent()
Q_D(QScriptDebuggerAgent);
if (d->backend)
d->backend->agentDestroyed(this);
-#if QT_VERSION < 0x040500
- delete d_ptr;
-#endif
}
/*!
@@ -712,12 +702,7 @@ void QScriptDebuggerAgent::exceptionCatch(qint64 scriptId,
*/
bool QScriptDebuggerAgent::supportsExtension(Extension extension) const
{
-#if QT_VERSION >= 0x040500
return (extension == DebuggerInvocationRequest);
-#else
- Q_UNUSED(extension);
- return false;
-#endif
}
/*!
@@ -727,7 +712,6 @@ QVariant QScriptDebuggerAgent::extension(Extension extension,
const QVariant &argument)
{
Q_UNUSED(extension);
-#if QT_VERSION >= 0x040500
Q_D(QScriptDebuggerAgent);
Q_ASSERT(extension == DebuggerInvocationRequest);
QVariantList lst = argument.toList();
@@ -739,9 +723,6 @@ QVariant QScriptDebuggerAgent::extension(Extension extension,
d->backend->debuggerInvocationRequest(
scriptId, lineNumber, columnNumber);
}
-#else
- Q_UNUSED(argument);
-#endif
return QVariant();
}
diff --git a/src/scripttools/debugging/qscriptdebuggeragent_p.h b/src/scripttools/debugging/qscriptdebuggeragent_p.h
index 556b17b..28ec46a 100644
--- a/src/scripttools/debugging/qscriptdebuggeragent_p.h
+++ b/src/scripttools/debugging/qscriptdebuggeragent_p.h
@@ -125,9 +125,6 @@ public:
const QVariant &argument = QVariant());
private:
-#if QT_VERSION < 0x040500
- QScriptDebuggerAgentPrivate *d_ptr;
-#endif
Q_DECLARE_PRIVATE(QScriptDebuggerAgent)
Q_DISABLE_COPY(QScriptDebuggerAgent)
};
diff --git a/src/scripttools/debugging/qscriptdebuggeragent_p_p.h b/src/scripttools/debugging/qscriptdebuggeragent_p_p.h
index cf6fd1a..313b1c0 100644
--- a/src/scripttools/debugging/qscriptdebuggeragent_p_p.h
+++ b/src/scripttools/debugging/qscriptdebuggeragent_p_p.h
@@ -68,9 +68,7 @@ QT_BEGIN_NAMESPACE
class QScriptDebuggerAgent;
class QScriptDebuggerAgentPrivate
-#if QT_VERSION >= 0x040500
: public QScriptEngineAgentPrivate
-#endif
{
Q_DECLARE_PUBLIC(QScriptDebuggerAgent)
public:
@@ -125,10 +123,6 @@ public:
int statementCounter;
QScriptDebuggerBackendPrivate *backend;
-
-#if QT_VERSION < 0x040500
- QScriptDebuggerAgent *q_ptr;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/scripttools/debugging/qscriptdebuggerbackend.cpp b/src/scripttools/debugging/qscriptdebuggerbackend.cpp
index 24a3847..3c29130 100644
--- a/src/scripttools/debugging/qscriptdebuggerbackend.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerbackend.cpp
@@ -615,13 +615,11 @@ void QScriptDebuggerBackend::doPendingEvaluate(bool postEvent)
// push a new context and initialize its scope chain etc.
{
QScriptContext *evalContext = engine()->pushContext();
-#if QT_VERSION >= 0x040500
QScriptValueList scopeChain = ctx->scopeChain();
if (scopeChain.isEmpty())
scopeChain.append(engine()->globalObject());
while (!scopeChain.isEmpty())
evalContext->pushScope(scopeChain.takeLast());
-#endif
evalContext->setActivationObject(ctx->activationObject());
evalContext->setThisObject(ctx->thisObject());
}
diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
index e36386d..1be8c5f 100644
--- a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
+++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp
@@ -287,13 +287,9 @@ QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
QScriptContext *ctx = backend->context(command.contextIndex());
if (ctx) {
QScriptDebuggerValueList dest;
-#if QT_VERSION >= 0x040500
QScriptValueList src = ctx->scopeChain();
for (int i = 0; i < src.size(); ++i)
dest.append(src.at(i));
-#else
- dest.append(ctx->activationObject());
-#endif
response.setResult(dest);
} else {
response.setError(QScriptDebuggerResponse::InvalidContextIndex);
diff --git a/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp
index 0018b92..f923508 100644
--- a/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerconsoleglobalobject.cpp
@@ -448,12 +448,7 @@ QStringList QScriptDebuggerConsoleGlobalObject::getCommandCompletions(const QStr
bool QScriptDebuggerConsoleGlobalObject::checkSyntax(const QString &program)
{
-#if QT_VERSION >= 0x040500
return (QScriptEngine::checkSyntax(program).state() == QScriptSyntaxCheckResult::Valid);
-#else
- Q_UNUSED(program);
- return true;
-#endif
}
void QScriptDebuggerConsoleGlobalObject::setEvaluateAction(int action)
diff --git a/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp
index a4919be..60fe48d 100644
--- a/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerlocalswidget.cpp
@@ -206,11 +206,7 @@ private Q_SLOTS:
QWidget *editor = qobject_cast<QWidget*>(sender());
QPalette pal = editor->palette();
QColor col;
-#if QT_VERSION >= 0x040500
bool ok = (QScriptEngine::checkSyntax(text).state() == QScriptSyntaxCheckResult::Valid);
-#else
- bool ok = true;
-#endif
if (ok) {
col = Qt::white;
} else {
@@ -277,12 +273,10 @@ bool QScriptDebuggerLocalsItemDelegate::eventFilter(QObject *watched, QEvent *ev
return QStyledItemDelegate::eventFilter(watched, event);
QKeyEvent *ke = static_cast<QKeyEvent*>(event);
if ((ke->key() == Qt::Key_Enter) || (ke->key() == Qt::Key_Return)) {
-#if QT_VERSION >= 0x040500
if (QScriptEngine::checkSyntax(le->text()).state() != QScriptSyntaxCheckResult::Valid) {
// ignore when script contains syntax error
return true;
}
-#endif
}
if (ke->key() != Qt::Key_Tab)
return QStyledItemDelegate::eventFilter(watched, event);
@@ -296,14 +290,12 @@ void QScriptDebuggerLocalsItemDelegate::setModelData(
QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
-#if QT_VERSION >= 0x040500
if (index.column() == 1) {
// check that the syntax is OK
QString expression = qobject_cast<QLineEdit*>(editor)->text();
if (QScriptEngine::checkSyntax(expression).state() != QScriptSyntaxCheckResult::Valid)
return;
}
-#endif
QStyledItemDelegate::setModelData(editor, model, index);
}
diff --git a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
index 20350f6..fa30d84 100644
--- a/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
+++ b/src/scripttools/debugging/qscriptdebuggerscriptedconsolecommand.cpp
@@ -410,11 +410,7 @@ void QScriptDebuggerScriptedConsoleCommandJob::start()
for (int i = 0; i < d->arguments.size(); ++i)
args.append(QScriptValue(engine, d->arguments.at(i)));
QScriptDebuggerConsoleGlobalObject *global;
-#if QT_VERSION >= 0x040500
global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
-#else
- global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().scope().toQObject());
-#endif
Q_ASSERT(global != 0);
global->setScheduler(this);
global->setResponseHandler(this);
@@ -444,11 +440,7 @@ void QScriptDebuggerScriptedConsoleCommandJob::handleResponse(
args.append(qScriptValueFromValue(engine, response));
args.append(QScriptValue(engine, commandId));
QScriptDebuggerConsoleGlobalObject *global;
-#if QT_VERSION >= 0x040500
global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().toQObject());
-#else
- global = qobject_cast<QScriptDebuggerConsoleGlobalObject*>(engine->globalObject().scope().toQObject());
-#endif
Q_ASSERT(global != 0);
global->setScheduler(this);
global->setResponseHandler(this);
@@ -566,12 +558,7 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa
QScriptDebuggerConsoleGlobalObject *cppGlobal = new QScriptDebuggerConsoleGlobalObject();
QScriptValue global = engine->newQObject(cppGlobal,
QScriptEngine::ScriptOwnership,
-#if QT_VERSION >= 0x040500
QScriptEngine::ExcludeSuperClassContents);
-#else
- QScriptEngine::ExcludeSuperClassMethods
- | QScriptEngine::ExcludeSuperClassProperties);
-#endif
{
QScriptValueIterator it(engine->globalObject());
while (it.hasNext()) {
@@ -579,12 +566,7 @@ QScriptDebuggerScriptedConsoleCommand *QScriptDebuggerScriptedConsoleCommand::pa
global.setProperty(it.scriptName(), it.value(), it.flags());
}
}
-#if QT_VERSION >= 0x040500
engine->setGlobalObject(global);
-#else
- engine->globalObject().setScope(global);
- global = engine->globalObject();
-#endif
cppGlobal->setMessageHandler(messageHandler);
QScriptValue ret = engine->evaluate(program, fileName);
diff --git a/src/scripttools/debugging/qscriptedit.cpp b/src/scripttools/debugging/qscriptedit.cpp
index 2bc0a40..7c2a72c 100644
--- a/src/scripttools/debugging/qscriptedit.cpp
+++ b/src/scripttools/debugging/qscriptedit.cpp
@@ -342,11 +342,9 @@ void QScriptEdit::extraAreaPaintEvent(QPaintEvent *e)
icon.paint(&painter, r, Qt::AlignCenter);
}
-#if QT_VERSION >= 0x040500
if (!m_executableLineNumbers.contains(lineNumber))
painter.setPen(pal.color(QPalette::Mid));
else
-#endif
painter.setPen(QColor(Qt::darkCyan));
QString number = QString::number(lineNumber);
painter.drawText(rect.x() + markWidth, (int)top, rect.x() + extraAreaWidth - markWidth - 4,
@@ -370,10 +368,8 @@ void QScriptEdit::extraAreaMouseEvent(QMouseEvent *e)
if (e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking
bool hand = (e->pos().x() <= markWidth);
-#if QT_VERSION >= 0x040500
int lineNumber = cursor.blockNumber() + m_baseLineNumber;
hand = hand && m_executableLineNumbers.contains(lineNumber);
-#endif
#ifndef QT_NO_CURSOR
if (hand != (m_extraArea->cursor().shape() == Qt::PointingHandCursor))
m_extraArea->setCursor(hand ? Qt::PointingHandCursor : Qt::ArrowCursor);
@@ -382,12 +378,8 @@ void QScriptEdit::extraAreaMouseEvent(QMouseEvent *e)
if (e->type() == QEvent::MouseButtonPress) {
if (e->button() == Qt::LeftButton) {
-#if QT_VERSION >= 0x040500
int lineNumber = cursor.blockNumber() + m_baseLineNumber;
bool executable = m_executableLineNumbers.contains(lineNumber);
-#else
- bool executable = true;
-#endif
if ((e->pos().x() <= markWidth) && executable)
m_extraAreaToggleBlockNumber = cursor.blockNumber();
else
@@ -402,10 +394,8 @@ void QScriptEdit::extraAreaMouseEvent(QMouseEvent *e)
}
} else if (e->button() == Qt::RightButton) {
int lineNumber = cursor.blockNumber() + m_baseLineNumber;
-#if QT_VERSION >= 0x040500
if (!m_executableLineNumbers.contains(lineNumber))
return;
-#endif
bool has = m_breakpoints.contains(lineNumber);
QMenu *popup = new QMenu();
QAction *toggleAct = new QAction(QObject::tr("Toggle Breakpoint"), popup);
diff --git a/src/scripttools/debugging/qscriptenginedebugger.h b/src/scripttools/debugging/qscriptenginedebugger.h
index d5e127f..a4853f0 100644
--- a/src/scripttools/debugging/qscriptenginedebugger.h
+++ b/src/scripttools/debugging/qscriptenginedebugger.h
@@ -48,11 +48,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-#if QT_VERSION >= 0x040500
QT_MODULE(ScriptTools)
-#else
-# define Q_SCRIPTTOOLS_EXPORT
-#endif
class QAction;
class QScriptEngine;
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 8e8bc56..11d0041 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -49,6 +49,7 @@
#include <qstringlist.h>
#include <qvarlengtharray.h>
#include <qvector.h>
+#include <QDebug>
#ifndef UNICODE
#define UNICODE
@@ -87,8 +88,19 @@ public:
{}
~QDB2ResultPrivate()
{
- for (int i = 0; i < valueCache.count(); ++i)
+ emptyValueCache();
+ }
+ void clearValueCache()
+ {
+ for (int i = 0; i < valueCache.count(); ++i) {
delete valueCache[i];
+ valueCache[i] = NULL;
+ }
+ }
+ void emptyValueCache()
+ {
+ clearValueCache();
+ valueCache.clear();
}
const QDB2DriverPrivate* dp;
@@ -544,7 +556,7 @@ bool QDB2Result::reset (const QString& query)
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly()))
return false;
@@ -568,6 +580,7 @@ bool QDB2Result::reset (const QString& query)
setSelect(false);
}
d->valueCache.resize(count);
+ d->valueCache.fill(NULL);
setActive(true);
return true;
}
@@ -579,7 +592,7 @@ bool QDB2Result::prepare(const QString& query)
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly()))
return false;
@@ -607,7 +620,7 @@ bool QDB2Result::exec()
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly(), false))
return false;
@@ -811,6 +824,7 @@ bool QDB2Result::exec()
}
setActive(true);
d->valueCache.resize(count);
+ d->valueCache.fill(NULL);
//get out parameters
if (!hasOutValues())
@@ -858,7 +872,7 @@ bool QDB2Result::fetch(int i)
return false;
if (i == at())
return true;
- d->valueCache.fill(0);
+ d->clearValueCache();
int actualIdx = i + 1;
if (actualIdx <= 0) {
setAt(QSql::BeforeFirstRow);
@@ -887,7 +901,7 @@ bool QDB2Result::fetch(int i)
bool QDB2Result::fetchNext()
{
SQLRETURN r;
- d->valueCache.fill(0);
+ d->clearValueCache();
r = SQLFetchScroll(d->hStmt,
SQL_FETCH_NEXT,
0);
@@ -907,7 +921,7 @@ bool QDB2Result::fetchFirst()
return false;
if (isForwardOnly())
return fetchNext();
- d->valueCache.fill(0);
+ d->clearValueCache();
SQLRETURN r;
r = SQLFetchScroll(d->hStmt,
SQL_FETCH_FIRST,
@@ -923,7 +937,7 @@ bool QDB2Result::fetchFirst()
bool QDB2Result::fetchLast()
{
- d->valueCache.fill(0);
+ d->clearValueCache();
int i = at();
if (i == QSql::AfterLastRow) {
@@ -1044,7 +1058,7 @@ QVariant QDB2Result::data(int field)
case QSql::HighPrecision:
default:
// length + 1 for the comma
- v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull));
+ v = new QVariant(value);
ok = true;
break;
}
@@ -1101,7 +1115,7 @@ bool QDB2Result::nextResult()
setActive(false);
setAt(QSql::BeforeFirstRow);
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
setSelect(false);
SQLRETURN r = SQLMoreResults(d->hStmt);
@@ -1120,6 +1134,7 @@ bool QDB2Result::nextResult()
d->recInf.append(qMakeFieldInfo(d, i));
d->valueCache.resize(fieldCount);
+ d->valueCache.fill(NULL);
setActive(true);
return true;
@@ -1167,7 +1182,7 @@ QDB2Driver::~QDB2Driver()
delete d;
}
-bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int,
+bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
const QString& connOpts)
{
if (isOpen())
@@ -1190,6 +1205,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
setOpenError(true);
return false;
}
+
+ QString protocol;
// Set connection attributes
const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
for (int i = 0; i < opts.count(); ++i) {
@@ -1220,7 +1237,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
} else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) {
v = val.toUInt();
r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0);
- } else {
+ } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) {
+ protocol = tmp;
+ }
+ else {
qWarning("QDB2Driver::open: Unknown connection attribute '%s'",
tmp.toLocal8Bit().constData());
}
@@ -1229,9 +1249,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
"Unable to set connection attribute '%1'").arg(opt), d);
}
+ if (protocol.isEmpty())
+ protocol = QLatin1String("PROTOCOL=TCPIP");
+
+ if (port < 0 )
+ port = 50000;
+
QString connQStr;
- connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=")
- + password;
+ connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host
+ + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user
+ + QLatin1String(";PWD=") + password;
+
+
SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH];
SQLSMALLINT cb;
@@ -1250,7 +1279,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
return false;
}
- d->user = user.toUpper();
+ d->user = user;
setOpen(true);
setOpenError(false);
return true;
@@ -1295,10 +1324,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
SQLHANDLE hStmt;
QString catalog, schema, table;
- qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table);
+ qSplitTableQualifier(tableName, &catalog, &schema, &table);
if (schema.isEmpty())
schema = d->user;
+ if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
+ catalog = stripDelimiters(catalog, QSqlDriver::TableName);
+ else
+ catalog = catalog.toUpper();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toUpper();
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
+
SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
d->hDbc,
&hStmt);
@@ -1312,6 +1356,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
(SQLPOINTER) SQL_CURSOR_FORWARD_ONLY,
SQL_IS_UINTEGER);
+
+ //Aside: szSchemaName and szTableName parameters of SQLColumns
+ //are case sensitive search patterns, so no escaping is used.
r = SQLColumns(hStmt,
NULL,
0,
@@ -1392,7 +1439,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const
bool isNull;
QString fieldVal = qGetStringData(hStmt, 2, -1, isNull);
QString userVal = qGetStringData(hStmt, 1, -1, isNull);
- if (userVal != d->user)
+ QString user = d->user;
+ if ( isIdentifierEscaped(user, QSqlDriver::TableName))
+ user = stripDelimiters(user, QSqlDriver::TableName);
+ else
+ user = user.toUpper();
+
+ if (userVal != user)
fieldVal = userVal + QLatin1Char('.') + fieldVal;
tl.append(fieldVal);
r = SQLFetchScroll(hStmt,
@@ -1423,7 +1476,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const
return index;
}
QString catalog, schema, table;
- qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table);
+ qSplitTableQualifier(tablename, &catalog, &schema, &table);
+
+ if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
+ catalog = stripDelimiters(catalog, QSqlDriver::TableName);
+ else
+ catalog = catalog.toUpper();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toUpper();
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
+
r = SQLSetStmtAttr(hStmt,
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
@@ -1594,4 +1663,15 @@ QVariant QDB2Driver::handle() const
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
}
+QString QDB2Driver::escapeIdentifier(const QString &identifier, IdentifierType) const
+{
+ QString res = identifier;
+ if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
+ res.replace(QLatin1Char('"'), QLatin1String("\"\""));
+ res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
+ res.replace(QLatin1Char('.'), QLatin1String("\".\""));
+ }
+ return res;
+}
+
QT_END_NAMESPACE
diff --git a/src/sql/drivers/db2/qsql_db2.h b/src/sql/drivers/db2/qsql_db2.h
index fd1b702..6923027 100644
--- a/src/sql/drivers/db2/qsql_db2.h
+++ b/src/sql/drivers/db2/qsql_db2.h
@@ -110,6 +110,8 @@ public:
const QString& host,
int port,
const QString& connOpts);
+ QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+
private:
bool setAutoCommit(bool autoCommit);
QDB2DriverPrivate* d;
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index 64f13b5..0705722 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -1552,12 +1552,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const
QSqlQuery q(createResult());
q.setForwardOnly(true);
-
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, "
"b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG "
"FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
"WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
- "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' "
+ "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' "
"ORDER BY a.RDB$FIELD_POSITION"));
while (q.next()) {
@@ -1585,12 +1589,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const
if (!isOpen())
return index;
+ QString tablename = table;
+ if (isIdentifierEscaped(tablename, QSqlDriver::TableName))
+ tablename = stripDelimiters(tablename, QSqlDriver::TableName);
+ else
+ tablename = tablename.toUpper();
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE "
"FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d "
"WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
- "AND a.RDB$RELATION_NAME = '") + table.toUpper() +
+ "AND a.RDB$RELATION_NAME = '") + tablename +
QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME "
"AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME "
"AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME "
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 9b57f3c..a84e840 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -1314,7 +1314,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlQuery i(createResult());
QString stmt(QLatin1String("show index from %1;"));
QSqlRecord fil = record(tablename);
- i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName)));
+ i.exec(stmt.arg(tablename));
while (i.isActive() && i.next()) {
if (i.value(2).toString() == QLatin1String("PRIMARY")) {
idx.append(fil.field(i.value(4).toString()));
@@ -1329,10 +1329,14 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlRecord QMYSQLDriver::record(const QString& tablename) const
{
+ QString table=tablename;
+ if(isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QSqlRecord info;
if (!isOpen())
return info;
- MYSQL_RES* r = mysql_list_fields(d->mysql, tablename.toLocal8Bit().constData(), 0);
+ MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0);
if (!r) {
return info;
}
@@ -1443,4 +1447,15 @@ QString QMYSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType
return res;
}
+bool QMYSQLDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
+{
+ Q_UNUSED(type);
+ bool isLeftDelimited = (identifier.left(1) == QString(QLatin1Char('`')));
+ bool isRightDelimited = (identifier.right(1) == QString(QLatin1Char('`')));
+ if( identifier.size() > 2 && isLeftDelimited && isRightDelimited )
+ return true;
+ else
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/sql/drivers/mysql/qsql_mysql.h b/src/sql/drivers/mysql/qsql_mysql.h
index 97aa346..31d9dcf 100644
--- a/src/sql/drivers/mysql/qsql_mysql.h
+++ b/src/sql/drivers/mysql/qsql_mysql.h
@@ -123,6 +123,9 @@ public:
QVariant handle() const;
QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+protected Q_SLOTS:
+ bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const;
+
protected:
bool beginTransaction();
bool commitTransaction();
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index bc9ecda..fa9b5f0 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -489,7 +489,7 @@ QSqlError qMakeError(const QString& errString, QSqlError::ErrorType type, OCIErr
return QSqlError(errString, oraErrorString, type, errorCode);
}
-static QVariant::Type qDecodeOCIType(const QString& ocitype, int ocilen, int ociprec, int ociscale)
+QVariant::Type qDecodeOCIType(const QString& ocitype, QSql::NumericalPrecisionPolicy precisionPolicy)
{
QVariant::Type type = QVariant::Invalid;
if (ocitype == QLatin1String("VARCHAR2") || ocitype == QLatin1String("VARCHAR")
@@ -497,10 +497,26 @@ static QVariant::Type qDecodeOCIType(const QString& ocitype, int ocilen, int oci
|| ocitype == QLatin1String("CHAR") || ocitype == QLatin1String("NVARCHAR2")
|| ocitype == QLatin1String("NCHAR"))
type = QVariant::String;
- else if (ocitype == QLatin1String("NUMBER"))
- type = QVariant::Int;
- else if (ocitype == QLatin1String("FLOAT"))
- type = QVariant::Double;
+ else if (ocitype == QLatin1String("NUMBER")
+ || ocitype == QLatin1String("FLOAT")
+ || ocitype == QLatin1String("BINARY_FLOAT")
+ || ocitype == QLatin1String("BINARY_DOUBLE")) {
+ switch(precisionPolicy) {
+ case QSql::LowPrecisionInt32:
+ type = QVariant::Int;
+ break;
+ case QSql::LowPrecisionInt64:
+ type = QVariant::LongLong;
+ break;
+ case QSql::LowPrecisionDouble:
+ type = QVariant::Double;
+ break;
+ case QSql::HighPrecision:
+ default:
+ type = QVariant::String;
+ break;
+ }
+ }
else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB")
|| ocitype == QLatin1String("CLOB"))
type = QVariant::ByteArray;
@@ -512,18 +528,12 @@ static QVariant::Type qDecodeOCIType(const QString& ocitype, int ocilen, int oci
type = QVariant::DateTime;
else if (ocitype == QLatin1String("UNDEFINED"))
type = QVariant::Invalid;
- if (type == QVariant::Int) {
- if (ocilen == 22 && ociprec == 0 && ociscale == 0)
- type = QVariant::Double;
- if (ociscale > 0)
- type = QVariant::Double;
- }
if (type == QVariant::Invalid)
qWarning("qDecodeOCIType: unknown type: %s", ocitype.toLocal8Bit().constData());
return type;
}
-static QVariant::Type qDecodeOCIType(int ocitype)
+QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precisionPolicy)
{
QVariant::Type type = QVariant::Invalid;
switch (ocitype) {
@@ -550,7 +560,21 @@ static QVariant::Type qDecodeOCIType(int ocitype)
case SQLT_NUM:
case SQLT_VNU:
case SQLT_UIN:
- type = QVariant::String;
+ switch(precisionPolicy) {
+ case QSql::LowPrecisionInt32:
+ type = QVariant::Int;
+ break;
+ case QSql::LowPrecisionInt64:
+ type = QVariant::LongLong;
+ break;
+ case QSql::LowPrecisionDouble:
+ type = QVariant::Double;
+ break;
+ case QSql::HighPrecision:
+ default:
+ type = QVariant::String;
+ break;
+ }
break;
case SQLT_VBI:
case SQLT_BIN:
@@ -686,7 +710,7 @@ static OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param)
if (r != 0)
qOraWarning("qMakeOraField:", p->err);
- type = qDecodeOCIType(colType);
+ type = qDecodeOCIType(colType, p->precisionPolicy);
if (type == QVariant::Int) {
if (colLength == 22 && colPrecision == 0 && colScale == 0)
@@ -2074,7 +2098,7 @@ bool QOCIDriver::open(const QString & db,
setOpen(true);
setOpenError(false);
- d->user = user.toUpper();
+ d->user = user;
return true;
}
@@ -2176,8 +2200,15 @@ QStringList QOCIDriver::tables(QSql::TableType type) const
"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();
+
while (t.next()) {
- if (t.value(0).toString() != d->user)
+ if (t.value(0).toString() != user)
tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString());
else
tl.append(t.value(1).toString());
@@ -2213,10 +2244,10 @@ void qSplitTableAndOwner(const QString & tname, QString * tbl,
{
int i = tname.indexOf(QLatin1Char('.')); // prefixed with owner?
if (i != -1) {
- *tbl = tname.right(tname.length() - i - 1).toUpper();
- *owner = tname.left(i).toUpper();
+ *tbl = tname.right(tname.length() - i - 1);
+ *owner = tname.left(i);
} else {
- *tbl = tname.toUpper();
+ *tbl = tname;
}
}
@@ -2232,7 +2263,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const
QString stmt(QLatin1String("select column_name, data_type, data_length, "
"data_precision, data_scale, nullable, data_default%1"
"from all_tab_columns "
- "where upper(table_name)=%2"));
+ "where table_name=%2"));
if (d->serverVersion >= 9)
stmt = stmt.arg(QLatin1String(", char_length "));
else
@@ -2240,11 +2271,23 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const
bool buildRecordInfo = false;
QString table, owner, tmpStmt;
qSplitTableAndOwner(tablename, &table, &owner);
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
+
tmpStmt = stmt.arg(QLatin1Char('\'') + table + QLatin1Char('\''));
if (owner.isEmpty()) {
owner = d->user;
}
- tmpStmt += QLatin1String(" and upper(owner)='") + owner + QLatin1String("'");
+
+ if (isIdentifierEscaped(owner, QSqlDriver::TableName))
+ owner = stripDelimiters(owner, QSqlDriver::TableName);
+ else
+ owner = owner.toUpper();
+
+ tmpStmt += QLatin1String(" and owner='") + owner + QLatin1String("'");
t.setForwardOnly(true);
t.exec(tmpStmt);
if (!t.next()) { // try and see if the tablename is a synonym
@@ -2257,14 +2300,15 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const
} else {
buildRecordInfo = true;
}
+ QStringList keywords = QStringList() << QLatin1String("NUMBER") << QLatin1String("FLOAT") << QLatin1String("BINARY_FLOAT")
+ << QLatin1String("BINARY_DOUBLE");
if (buildRecordInfo) {
do {
- QVariant::Type ty = qDecodeOCIType(t.value(1).toString(), t.value(2).toInt(),
- t.value(3).toInt(), t.value(4).toInt());
+ QVariant::Type ty = qDecodeOCIType(t.value(1).toString(),t.numericalPrecisionPolicy());
QSqlField f(t.value(0).toString(), ty);
f.setRequired(t.value(5).toString() == QLatin1String("N"));
f.setPrecision(t.value(4).toInt());
- if (d->serverVersion >= 9 && (ty == QVariant::String) && !t.isNull(3)) {
+ if (d->serverVersion >= 9 && (ty == QVariant::String) && !t.isNull(3) && !keywords.contains(t.value(1).toString())) {
// Oracle9: data_length == size in bytes, char_length == amount of characters
f.setLength(t.value(7).toInt());
} else {
@@ -2292,11 +2336,23 @@ QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const
bool buildIndex = false;
QString table, owner, tmpStmt;
qSplitTableAndOwner(tablename, &table, &owner);
- tmpStmt = stmt + QLatin1String(" and upper(a.table_name)='") + table + QLatin1String("'");
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
+
+ tmpStmt = stmt + QLatin1String(" and a.table_name='") + table + QLatin1String("'");
if (owner.isEmpty()) {
owner = d->user;
}
- tmpStmt += QLatin1String(" and upper(a.owner)='") + owner + QLatin1String("'");
+
+ if (isIdentifierEscaped(owner, QSqlDriver::TableName))
+ owner = stripDelimiters(owner, QSqlDriver::TableName);
+ else
+ owner = owner.toUpper();
+
+ tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1String("'");
t.setForwardOnly(true);
t.exec(tmpStmt);
@@ -2324,7 +2380,7 @@ QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const
if (!tt.next()) {
return QSqlIndex();
}
- QSqlField f(t.value(0).toString(), qDecodeOCIType(tt.value(0).toString(), 0, 0, 0));
+ QSqlField f(t.value(0).toString(), qDecodeOCIType(tt.value(0).toString(), t.numericalPrecisionPolicy()));
idx.append(f);
} while (t.next());
return idx;
@@ -2390,13 +2446,14 @@ QVariant QOCIDriver::handle() const
return qVariantFromValue(d->env);
}
-QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType /* type */) const
+QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
{
QString res = identifier;
- res.replace(QLatin1Char('"'), QLatin1String("\"\""));
- if (identifier.indexOf(QLatin1Char(' ')) != -1)
+ if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type)) {
+ res.replace(QLatin1Char('"'), QLatin1String("\"\""));
res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
-// res.replace(QLatin1Char('.'), QLatin1String("\".\""));
+ res.replace(QLatin1Char('.'), QLatin1String("\".\""));
+ }
return res;
}
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index f6710db..2a83fe6 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -55,6 +55,7 @@
#include <qvarlengtharray.h>
#include <qvector.h>
#include <QDebug>
+#include <QSqlQuery>
QT_BEGIN_NAMESPACE
@@ -88,6 +89,7 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL
class QODBCDriverPrivate
{
public:
+ enum DefaultCase{Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate()
: hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false),
isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false)
@@ -119,6 +121,9 @@ public:
bool setConnectionOptions(const QString& connOpts);
void splitTableQualifier(const QString &qualifier, QString &catalog,
QString &schema, QString &table);
+ DefaultCase defaultCase() const;
+ QString adjustCase(const QString&) const;
+ QChar quoteChar() const;
};
class QODBCPrivate
@@ -350,7 +355,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
} else {
fieldVal += QString::fromAscii(buf, rSize);
}
- if (fieldVal.size() + lengthIndicator >= colSize) {
+ if (lengthIndicator - fieldVal.size() <= 0) {
// workaround for Drivermanagers that don't return SQL_NO_DATA
break;
}
@@ -555,6 +560,29 @@ static int qGetODBCVersion(const QString &connOpts)
return SQL_OV_ODBC2;
}
+QChar QODBCDriverPrivate::quoteChar() const
+{
+ static bool isQuoteInitialized = false;
+ static QChar quote = QChar::fromLatin1('"');
+ if (!isQuoteInitialized) {
+ char driverResponse[4];
+ SQLUSMALLINT casing;
+ SQLSMALLINT length;
+ int r = SQLGetInfo(hDbc,
+ SQL_IDENTIFIER_QUOTE_CHAR,
+ &driverResponse,
+ sizeof(driverResponse),
+ &length);
+ if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+ quote = QChar::fromLatin1(driverResponse[0]);
+ } else {
+ quote = QChar::fromLatin1('"');
+ }
+ isQuoteInitialized = true;
+ }
+ return quote;
+}
+
bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
{
// Set any connection attributes
@@ -705,6 +733,65 @@ void QODBCDriverPrivate::splitTableQualifier(const QString & qualifier, QString
}
}
+QODBCDriverPrivate::DefaultCase QODBCDriverPrivate::defaultCase() const
+{
+ static bool isInitialized = false;
+ static DefaultCase ret;
+
+ if (!isInitialized) {
+ SQLUSMALLINT casing;
+ int r = SQLGetInfo(hDbc,
+ SQL_IDENTIFIER_CASE,
+ &casing,
+ sizeof(casing),
+ NULL);
+ if ( r != SQL_SUCCESS)
+ ret = Lower;//arbitrary case if driver cannot be queried
+ else {
+ switch (casing) {
+ case (SQL_IC_UPPER):
+ ret = Upper;
+ break;
+ case (SQL_IC_LOWER):
+ ret = Lower;
+ break;
+ case (SQL_IC_SENSITIVE):
+ ret = Sensitive;
+ break;
+ case (SQL_IC_MIXED):
+ ret = Mixed;
+ break;
+ default:
+ ret = Upper;
+ }
+ }
+ isInitialized = true;
+ }
+ return ret;
+}
+
+/*
+ Adjust the casing of an identifier to match what the
+ database engine would have done to it.
+*/
+QString QODBCDriverPrivate::adjustCase(const QString &identifier) const
+{
+ QString ret = identifier;
+ switch(defaultCase()) {
+ case (Lower):
+ ret = identifier.toLower();
+ break;
+ case (Upper):
+ ret = identifier.toUpper();
+ break;
+ case(Mixed):
+ case(Sensitive):
+ default:
+ ret = identifier;
+ }
+ return ret;
+}
+
////////////////////////////////////////////////////////////////////////////
QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p)
@@ -1714,6 +1801,10 @@ bool QODBCDriver::open(const QString & db,
d->checkHasMultiResults();
setOpen(true);
setOpenError(false);
+ if(d->isMSSqlServer) {
+ QSqlQuery i(createResult());
+ i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON"));
+ }
return true;
}
@@ -2084,6 +2175,22 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
}
QString catalog, schema, table;
d->splitTableQualifier(tablename, catalog, schema, table);
+
+ if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
+ catalog = stripDelimiters(catalog, QSqlDriver::TableName);
+ else
+ catalog = d->adjustCase(catalog);
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = d->adjustCase(schema);
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = d->adjustCase(table);
+
r = SQLSetStmtAttr(hStmt,
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
@@ -2186,6 +2293,22 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const
SQLHANDLE hStmt;
QString catalog, schema, table;
d->splitTableQualifier(tablename, catalog, schema, table);
+
+ if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
+ catalog = stripDelimiters(catalog, QSqlDriver::TableName);
+ else
+ catalog = d->adjustCase(catalog);
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = d->adjustCase(schema);
+
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = d->adjustCase(table);
+
SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
d->hDbc,
&hStmt);
@@ -2309,4 +2432,15 @@ QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType)
return res;
}
+bool QODBCDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType) const
+{
+ QString quote = d->quoteChar();
+ bool isLeftDelimited = identifier.left(1) == quote;
+ bool isRightDelimited = identifier.right(1) == quote;
+ if( identifier.size() > 2 && isLeftDelimited && isRightDelimited )
+ return true;
+ else
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/sql/drivers/odbc/qsql_odbc.h b/src/sql/drivers/odbc/qsql_odbc.h
index 4148007..51f53ea 100644
--- a/src/sql/drivers/odbc/qsql_odbc.h
+++ b/src/sql/drivers/odbc/qsql_odbc.h
@@ -145,10 +145,14 @@ public:
QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+protected Q_SLOTS:
+ bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const;
+
protected:
bool beginTransaction();
bool commitTransaction();
bool rollbackTransaction();
+
private:
void init();
bool endTrans();
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index e33dd95..16d19f1 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -351,8 +351,9 @@ QVariant QPSQLResult::data(int i)
#ifndef QT_NO_DATESTRING
if (str.isEmpty())
return QVariant(QTime());
- if (str.at(str.length() - 3) == QLatin1Char('+'))
+ if (str.at(str.length() - 3) == QLatin1Char('+') || str.at(str.length() - 3) == QLatin1Char('-'))
// strip the timezone
+ // TODO: fix this when timestamp support comes into QDateTime
return QVariant(QTime::fromString(str.left(str.length() - 3), Qt::ISODate));
return QVariant(QTime::fromString(str, Qt::ISODate));
#else
@@ -365,7 +366,8 @@ QVariant QPSQLResult::data(int i)
if (dtval.length() < 10)
return QVariant(QDateTime());
// remove the timezone
- if (dtval.at(dtval.length() - 3) == QLatin1Char('+'))
+ // TODO: fix this when timestamp support comes into QDateTime
+ if (dtval.at(dtval.length() - 3) == QLatin1Char('+') || dtval.at(dtval.length() - 3) == QLatin1Char('-'))
dtval.chop(3);
// milliseconds are sometimes returned with 2 digits only
if (dtval.at(dtval.length() - 3).isPunct())
@@ -892,6 +894,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QString schema;
qSplitTableName(tbl, schema);
+ if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+ else
+ tbl = tbl.toLower();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toLower();
+
switch(d->pro) {
case QPSQLDriver::Version6:
stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname "
@@ -924,7 +936,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
"FROM pg_attribute, pg_class "
"WHERE %1 pg_class.oid IN "
"(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN "
- " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) "
+ " (SELECT oid FROM pg_class WHERE relname = '%2')) "
"AND pg_attribute.attrelid = pg_class.oid "
"AND pg_attribute.attisdropped = false "
"ORDER BY pg_attribute.attnum");
@@ -932,11 +944,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND"));
else
stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower()));
+ "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema));
break;
}
- i.exec(stmt.arg(tbl.toLower()));
+ i.exec(stmt.arg(tbl));
while (i.isActive() && i.next()) {
QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt()));
idx.append(f);
@@ -955,6 +967,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString schema;
qSplitTableName(tbl, schema);
+ if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+ else
+ tbl = tbl.toLower();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toLower();
+
QString stmt;
switch(d->pro) {
case QPSQLDriver::Version6:
@@ -999,7 +1021,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
"left join pg_attrdef on (pg_attrdef.adrelid = "
"pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
"where %1 "
- "and lower(pg_class.relname) = '%2' "
+ "and pg_class.relname = '%2' "
"and pg_attribute.attnum > 0 "
"and pg_attribute.attrelid = pg_class.oid "
"and pg_attribute.attisdropped = false "
@@ -1008,12 +1030,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)"));
else
stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower()));
+ "pg_namespace where pg_namespace.nspname = '%1')").arg(schema));
break;
}
QSqlQuery query(createResult());
- query.exec(stmt.arg(tbl.toLower()));
+ query.exec(stmt.arg(tbl));
if (d->pro >= QPSQLDriver::Version71) {
while (query.next()) {
int len = query.value(3).toInt();
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 605c4e8..f732077 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -661,9 +661,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const
if (!isOpen())
return QSqlIndex();
+ QString table = tblname;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
- return qGetTableInfo(q, tblname, true);
+ return qGetTableInfo(q, table, true);
}
QSqlRecord QSQLiteDriver::record(const QString &tbl) const
@@ -671,9 +675,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const
if (!isOpen())
return QSqlRecord();
+ QString table = tbl;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
- return qGetTableInfo(q, tbl);
+ return qGetTableInfo(q, table);
}
QVariant QSQLiteDriver::handle() const
@@ -681,10 +689,10 @@ QVariant QSQLiteDriver::handle() const
return qVariantFromValue(d->access);
}
-QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const
+QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
{
QString res = identifier;
- if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
+ if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) {
res.replace(QLatin1Char('"'), QLatin1String("\"\""));
res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
res.replace(QLatin1Char('.'), QLatin1String("\".\""));
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index a40dc08..d0c6e18 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -167,7 +167,15 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
for (int i = 0; i < numCols; ++i) {
const char* lastDot = strrchr(cnames[i], '.');
const char* fieldName = lastDot ? lastDot + 1 : cnames[i];
- rInf.append(QSqlField(QString::fromAscii(fieldName),
+
+ //remove quotations around the field name if any
+ QString fieldStr = QString::fromAscii(fieldName);
+ QString quote = QString::fromLatin1("\"");
+ if ( fieldStr.length() > 2 && fieldStr.left(1) == quote && fieldStr.right(1) == quote) {
+ fieldStr = fieldStr.mid(1);
+ fieldStr.chop(1);
+ }
+ rInf.append(QSqlField(fieldStr,
nameToType(QString::fromAscii(cnames[i+numCols]))));
}
}
@@ -297,6 +305,11 @@ bool QSQLite2Result::reset (const QString& query)
// we have to fetch one row to find out about
// the structure of the result set
d->skippedStatus = d->fetchNext(cache(), 0, true);
+ if (lastError().isValid()) {
+ setSelect(false);
+ setActive(false);
+ return false;
+ }
setSelect(!d->rInf.isEmpty());
setActive(true);
return true;
@@ -498,8 +511,11 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const
QSqlQuery q(createResult());
q.setForwardOnly(true);
+ QString table = tblname;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
// finrst find a UNIQUE INDEX
- q.exec(QLatin1String("PRAGMA index_list('") + tblname + QLatin1String("');"));
+ q.exec(QLatin1String("PRAGMA index_list('") + table + QLatin1String("');"));
QString indexname;
while(q.next()) {
if (q.value(2).toInt()==1) {
@@ -512,7 +528,7 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const
q.exec(QLatin1String("PRAGMA index_info('") + indexname + QLatin1String("');"));
- QSqlIndex index(tblname, indexname);
+ QSqlIndex index(table, indexname);
while(q.next()) {
QString name = q.value(2).toString();
QVariant::Type type = QVariant::Invalid;
@@ -527,6 +543,9 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const
{
if (!isOpen())
return QSqlRecord();
+ QString table = tbl;
+ if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
QSqlQuery q(createResult());
q.setForwardOnly(true);
diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp
index 46e4a0b..515f0de 100644
--- a/src/sql/drivers/tds/qsql_tds.cpp
+++ b/src/sql/drivers/tds/qsql_tds.cpp
@@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
// insert d in error handler dict
errs()->insert(d->dbproc, d);
+ dbcmd(d->dbproc, "set quoted_identifier on");
+ dbsqlexec(d->dbproc);
}
QTDSResult::~QTDSResult()
@@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
if (qIsNull(d->buffer.at(i * 2 + 1)))
values[idx] = QVariant(QVariant::String);
else
- values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2));
+ values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed();
break;
case QVariant::ByteArray: {
if (qIsNull(d->buffer.at(i * 2 + 1)))
@@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const
return info;
QSqlQuery t(createResult());
t.setForwardOnly(true);
+
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QString stmt (QLatin1String("select name, type, length, prec from syscolumns "
"where id = (select id from sysobjects where name = '%1')"));
- t.exec(stmt.arg(tablename));
+ t.exec(stmt.arg(table));
while (t.next()) {
QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt()));
f.setLength(t.value(2).toInt());
@@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const
{
QSqlRecord rec = record(tablename);
- QSqlIndex idx(tablename);
- if ((!isOpen()) || (tablename.isEmpty()))
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
+ QSqlIndex idx(table);
+ if ((!isOpen()) || (table.isEmpty()))
return QSqlIndex();
QSqlQuery t(createResult());
t.setForwardOnly(true);
- t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename));
+ t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table));
if (t.next()) {
QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(','));
QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*"));
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index ddebe45..40bc0df 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -49,6 +49,17 @@
QT_BEGIN_NAMESPACE
+static QString prepareIdentifier(const QString &identifier,
+ QSqlDriver::IdentifierType type, const QSqlDriver *driver)
+{
+ Q_ASSERT( driver != NULL );
+ QString ret = identifier;
+ if (!driver->isIdentifierEscaped(identifier, type)) {
+ ret = driver->escapeIdentifier(identifier, type);
+ }
+ return ret;
+}
+
class QSqlDriverPrivate : public QObjectPrivate
{
public:
@@ -372,6 +383,7 @@ QSqlRecord QSqlDriver::record(const QString & /* tableName */) const
on \a type.
The default implementation does nothing.
+ \sa isIdentifierEscaped()
*/
QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
{
@@ -379,6 +391,55 @@ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType)
}
/*!
+ Returns whether \a identifier is escaped according to the database rules.
+ \a identifier can either be a table name or field name, dependent
+ on \a type.
+
+ \warning Because of binary compatability constraints, this function is not virtual.
+ If you want to provide your own implementation in your QSqlDriver subclass,
+ reimplement the isIdentifierEscapedImplementation() slot in your subclass instead.
+ The isIdentifierEscapedFunction() will dynamically detect the slot and call it.
+
+ \sa stripDelimiters(), escapeIdentifier()
+ */
+bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const
+{
+ bool result;
+ QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
+ "isIdentifierEscapedImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, result),
+ Q_ARG(QString, identifier),
+ Q_ARG(IdentifierType, type));
+ return result;
+}
+
+/*!
+ Returns the \a identifier with the leading and trailing delimiters removed,
+ \a identifier can either be a table name or field name,
+ dependent on \a type. If \a identifier does not have leading
+ and trailing delimiter characters, \a identifier is returned without
+ modification.
+
+ \warning Because of binary compatability constraints, this function is not virtual,
+ If you want to provide your own implementation in your QSqlDriver subclass,
+ reimplement the stripDelimitersImplementation() slot in your subclass instead.
+ The stripDelimiters() function will dynamically detect the slot and call it.
+
+ \since 4.5
+ \sa isIdentifierEscaped()
+ */
+QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const
+{
+ QString result;
+ QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
+ "stripDelimitersImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QString, result),
+ Q_ARG(QString, identifier),
+ Q_ARG(IdentifierType, type));
+ return result;
+}
+
+/*!
Returns a SQL statement of type \a type for the table \a tableName
with the values from \a rec. If \a preparedStatement is true, the
string will contain placeholders instead of values.
@@ -397,21 +458,26 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
case SelectStatement:
for (i = 0; i < rec.count(); ++i) {
if (rec.isGenerated(i))
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
}
if (s.isEmpty())
return s;
s.chop(2);
- s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(escapeIdentifier(tableName, TableName));
+ s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
break;
case WhereStatement:
if (preparedStatement) {
- for (int i = 0; i < rec.count(); ++i)
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(
- QLatin1String(" = ? AND "));
+ for (int i = 0; i < rec.count(); ++i) {
+ s.append(prepareIdentifier(rec.fieldName(i), FieldName,this));
+ if (rec.isNull(i))
+ s.append(QLatin1String(" IS NULL"));
+ else
+ s.append(QLatin1String(" = ?"));
+ s.append(QLatin1String(" AND "));
+ }
} else {
for (i = 0; i < rec.count(); ++i) {
- s.append(escapeIdentifier(rec.fieldName(i), FieldName));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this));
QString val = formatValue(rec.field(i));
if (val == QLatin1String("NULL"))
s.append(QLatin1String(" IS NULL"));
@@ -426,12 +492,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
}
break;
case UpdateStatement:
- s.append(QLatin1String("UPDATE ")).append(escapeIdentifier(tableName, TableName)).append(
+ s.append(QLatin1String("UPDATE ")).append(tableName).append(
QLatin1String(" SET "));
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i) || !rec.value(i).isValid())
continue;
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('='));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('='));
if (preparedStatement)
s.append(QLatin1Char('?'));
else
@@ -444,15 +510,15 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
s.clear();
break;
case DeleteStatement:
- s.append(QLatin1String("DELETE FROM ")).append(escapeIdentifier(tableName, TableName));
+ s.append(QLatin1String("DELETE FROM ")).append(tableName);
break;
case InsertStatement: {
- s.append(QLatin1String("INSERT INTO ")).append(escapeIdentifier(tableName, TableName)).append(QLatin1String(" ("));
+ s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
QString vals;
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i) || !rec.value(i).isValid())
continue;
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
if (preparedStatement)
vals.append(QLatin1String("?"));
else
@@ -800,4 +866,56 @@ QStringList QSqlDriver::subscribedToNotificationsImplementation() const
return QStringList();
}
+/*!
+ This slot returns whether \a identifier is escaped according to the database rules.
+ \a identifier can either be a table name or field name, dependent
+ on \a type.
+
+ Because of binary compatability constraints, isIdentifierEscaped() function
+ (introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will
+ dynamically detect and call \e this slot. The default implementation
+ assumes the escape/delimiter character is a double quote. Reimplement this
+ slot in your own QSqlDriver if your database engine uses a different
+ delimiter character.
+
+ \since 4.5
+ \sa isIdentifierEscaped()
+ */
+bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
+{
+ Q_UNUSED(type);
+ bool isLeftDelimited = identifier.left(1) == QString(QLatin1Char('"'));
+ bool isRightDelimited = identifier.right(1) == QString(QLatin1Char('"'));
+ if( identifier.size() > 2 && isLeftDelimited && isRightDelimited )
+ return true;
+ else
+ return false;
+}
+
+/*!
+ This slot returns \a identifier with the leading and trailing delimiters removed,
+ \a identifier can either be a tablename or field name, dependent on \a type.
+ If \a identifier does not have leading and trailing delimiter characters, \a
+ identifier is returned without modification.
+
+ Because of binary compatability constraints, the stripDelimiters() function
+ (introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will
+ dynamically detect and call \e this slot. It generally unnecessary
+ to reimplement this slot.
+
+ \since 4.5
+ \sa stripDelimiters()
+ */
+QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const
+{
+ QString ret;
+ if (this->isIdentifierEscaped(identifier, type)) {
+ ret = identifier.mid(1);
+ ret.chop(1);
+ } else {
+ ret = identifier;
+ }
+ return ret;
+}
+
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index e763719..8ac1471 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -127,6 +127,9 @@ public:
bool unsubscribeFromNotification(const QString &name); // ### Qt 5: make virtual
QStringList subscribedToNotifications() const; // ### Qt 5: make virtual
+ bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual
+ QString stripDelimiters(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual
+
Q_SIGNALS:
void notification(const QString &name);
@@ -140,6 +143,9 @@ protected Q_SLOTS:
bool unsubscribeFromNotificationImplementation(const QString &name); // ### Qt 5: eliminate, see unsubscribeFromNotification()
QStringList subscribedToNotificationsImplementation() const; // ### Qt 5: eliminate, see subscribedNotifications()
+ bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see isIdentifierEscaped()
+ QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see stripDelimiters()
+
private:
Q_DISABLE_COPY(QSqlDriver)
};
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 935466b..12eae84 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -182,10 +182,21 @@ void QRelation::populateDictionary()
populateModel();
QSqlRecord record;
+ QString indexColumn;
+ QString displayColumn;
for (int i=0; i < model->rowCount(); ++i) {
record = model->record(i);
- dictionary[record.field(rel.indexColumn()).value().toString()] =
- record.field(rel.displayColumn()).value();
+
+ indexColumn = rel.indexColumn();
+ if (m_parent->database().driver()->isIdentifierEscaped(indexColumn, QSqlDriver::FieldName))
+ indexColumn = m_parent->database().driver()->stripDelimiters(indexColumn, QSqlDriver::FieldName);
+
+ displayColumn = rel.displayColumn();
+ if (m_parent->database().driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
+ displayColumn = m_parent->database().driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
+
+ dictionary[record.field(indexColumn).value().toString()] =
+ record.field(displayColumn).value();
}
m_dictInitialized = true;
}
@@ -215,7 +226,7 @@ public:
QSqlRelationalTableModelPrivate()
: QSqlTableModelPrivate()
{}
- QString escapedRelationField(const QString &tableName, const QString &fieldName) const;
+ QString relationField(const QString &tableName, const QString &fieldName) const;
int nameToIndex(const QString &name) const;
mutable QVector<QRelation> relations;
@@ -255,7 +266,10 @@ void QSqlRelationalTableModelPrivate::revertCachedRow(int row)
int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const
{
- return baseRec.indexOf(name);
+ QString fieldname = name;
+ if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
+ fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
+ return baseRec.indexOf(fieldname);
}
void QSqlRelationalTableModelPrivate::clearEditBuffer()
@@ -481,14 +495,14 @@ QSqlRelation QSqlRelationalTableModel::relation(int column) const
return d->relations.value(column).rel;
}
-QString QSqlRelationalTableModelPrivate::escapedRelationField(const QString &tableName,
+QString QSqlRelationalTableModelPrivate::relationField(const QString &tableName,
const QString &fieldName) const
{
- QString esc;
- esc.reserve(tableName.size() + fieldName.size() + 1);
- esc.append(tableName).append(QLatin1Char('.')).append(fieldName);
+ QString ret;
+ ret.reserve(tableName.size() + fieldName.size() + 1);
+ ret.append(tableName).append(QLatin1Char('.')).append(fieldName);
- return db.driver()->escapeIdentifier(esc, QSqlDriver::FieldName);
+ return ret;
}
/*!
@@ -514,15 +528,29 @@ QString QSqlRelationalTableModel::selectStatement() const
// Count how many times each field name occurs in the record
QHash<QString, int> fieldNames;
+ QStringList fieldList;
for (int i = 0; i < rec.count(); ++i) {
QSqlRelation relation = d->relations.value(i, nullRelation).rel;
QString name;
if (relation.isValid())
+ {
// Count the display column name, not the original foreign key
name = relation.displayColumn();
+ if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName))
+ name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName);
+
+ QSqlRecord rec = database().record(relation.tableName());
+ for (int i = 0; i < rec.count(); ++i) {
+ if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) {
+ name = rec.fieldName(i);
+ break;
+ }
+ }
+ }
else
name = rec.fieldName(i);
fieldNames.insert(name, fieldNames.value(name, 0) + 1);
+ fieldList.append(name);
}
for (int i = 0; i < rec.count(); ++i) {
@@ -531,27 +559,30 @@ QString QSqlRelationalTableModel::selectStatement() const
QString relTableAlias = QString::fromLatin1("relTblAl_%1").arg(i);
if (!fList.isEmpty())
fList.append(QLatin1String(", "));
- fList.append(d->escapedRelationField(relTableAlias, relation.displayColumn()));
+ fList.append(d->relationField(relTableAlias,relation.displayColumn()));
// If there are duplicate field names they must be aliased
- if (fieldNames.value(relation.displayColumn()) > 1) {
- fList.append(QString::fromLatin1(" AS %1_%2").arg(relation.tableName()).arg(relation.displayColumn()));
+ if (fieldNames.value(fieldList[i]) > 1) {
+ QString relTableName = relation.tableName();
+ if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName))
+ relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName);
+ QString displayColumn = relation.displayColumn();
+ if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
+ displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
+ fList.append(QString::fromLatin1(" AS %1_%2").arg(relTableName).arg(displayColumn));
}
// this needs fixing!! the below if is borken.
- if (!tables.contains(relation.tableName()))
- tables.append(d->db.driver()->escapeIdentifier(relation.tableName(),QSqlDriver::TableName)
- .append(QLatin1String(" "))
- .append(d->db.driver()->escapeIdentifier(relTableAlias, QSqlDriver::TableName)));
+ tables.append(relation.tableName().append(QLatin1String(" ")).append(relTableAlias));
if(!where.isEmpty())
where.append(QLatin1String(" AND "));
- where.append(d->escapedRelationField(tableName(), rec.fieldName(i)));
+ where.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName)));
where.append(QLatin1String(" = "));
- where.append(d->escapedRelationField(relTableAlias, relation.indexColumn()));
+ where.append(d->relationField(relTableAlias, relation.indexColumn()));
} else {
if (!fList.isEmpty())
fList.append(QLatin1String(", "));
- fList.append(d->escapedRelationField(tableName(), rec.fieldName(i)));
+ fList.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName)));
}
}
if (!tables.isEmpty())
@@ -560,7 +591,7 @@ QString QSqlRelationalTableModel::selectStatement() const
return query;
if(!tList.isEmpty())
tList.prepend(QLatin1String(", "));
- tList.prepend(d->db.driver()->escapeIdentifier(tableName(),QSqlDriver::TableName));
+ tList.prepend(tableName());
query.append(QLatin1String("SELECT "));
query.append(fList).append(QLatin1String(" FROM ")).append(tList);
qAppendWhereClause(query, where, filter());
@@ -690,7 +721,7 @@ QString QSqlRelationalTableModel::orderByClause() const
return QSqlTableModel::orderByClause();
QString s = QLatin1String("ORDER BY ");
- s.append(d->escapedRelationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn),
+ s.append(d->relationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn),
rel.displayColumn()));
s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC");
return s;
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 2fb9b0f..c2442c5 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record)
int QSqlTableModelPrivate::nameToIndex(const QString &name) const
{
- return rec.indexOf(name);
+ QString fieldname = name;
+ if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
+ fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
+ return rec.indexOf(fieldname);
}
void QSqlTableModelPrivate::initRecordAndPrimaryIndex()
@@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName)
{
Q_D(QSqlTableModel);
clear();
- if(d->db.tables().contains(tableName.toUpper()))
- d->tableName = tableName.toUpper();
- else
- d->tableName = tableName;
+ d->tableName = tableName;
d->initRecordAndPrimaryIndex();
d->initColOffsets(d->rec.count());
@@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const
if (!f.isValid())
return s;
- QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName);
+ QString table = d->tableName;
+ //we can safely escape the field because it would have been obtained from the database
+ //and have the correct case
QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field);
s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC");
@@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record)
mrow.rec = d->rec;
mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row());
}
+ QString fieldName;
for (int i = 0; i < record.count(); ++i) {
- int idx = mrow.rec.indexOf(record.fieldName(i));
+ fieldName = record.fieldName(i);
+ if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName))
+ fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName);
+ int idx = mrow.rec.indexOf(fieldName);
if (idx == -1)
isOk = false;
else
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
index f7b2ae8..e822da5 100644
--- a/src/svg/qsvggenerator.cpp
+++ b/src/svg/qsvggenerator.cpp
@@ -516,7 +516,34 @@ public:
\brief The QSvgGenerator class provides a paint device that is used to create SVG drawings.
\reentrant
- \sa QSvgRenderer, QSvgWidget
+ This paint device represents a Scalable Vector Graphics (SVG) drawing. Like QPrinter, it is
+ designed as a write-only device that generates output in a specific format.
+
+ To write an SVG file, you first need to configure the output by setting the \l fileName
+ or \l outputDevice properties. It is usually necessary to specify the size of the drawing
+ by setting the \l size property, and in some cases where the drawing will be included in
+ another, the \l viewBox property also needs to be set.
+
+ \snippet examples/painting/svggenerator/window.cpp configure SVG generator
+
+ Other meta-data can be specified by setting the \a title, \a description and \a resolution
+ properties.
+
+ As with other QPaintDevice subclasses, a QPainter object is used to paint onto an instance
+ of this class:
+
+ \snippet examples/painting/svggenerator/window.cpp begin painting
+ \dots
+ \snippet examples/painting/svggenerator/window.cpp end painting
+
+ Painting is performed in the same way as for any other paint device. However,
+ it is necessary to use the QPainter::begin() and \l{QPainter::}{end()} to
+ explicitly begin and end painting on the device.
+
+ The \l{SVG Generator Example} shows how the same painting commands can be used
+ for painting a widget and writing an SVG file.
+
+ \sa QSvgRenderer, QSvgWidget, {About SVG}
*/
/*!
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 56dab5f..433a3ad 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -2587,10 +2587,12 @@ static void parseBaseGradient(QSvgNode *node,
if (prop && prop->type() == QSvgStyleProperty::GRADIENT) {
QSvgGradientStyle *inherited =
static_cast<QSvgGradientStyle*>(prop);
- if (!inherited->stopLink().isEmpty())
+ if (!inherited->stopLink().isEmpty()) {
gradProp->setStopLink(inherited->stopLink(), handler->document());
- else
+ } else {
grad->setStops(inherited->qgradient()->stops());
+ gradProp->setGradientStopsSet(inherited->gradientStopsSet());
+ }
matrix = inherited->qmatrix();
} else {
@@ -2649,7 +2651,6 @@ static QSvgStyleProperty *createLinearGradientNode(QSvgNode *node,
}
QLinearGradient *grad = new QLinearGradient(nx1, ny1, nx2, ny2);
- grad->setColorAt(qQNaN(), QColor());
grad->setInterpolationMode(QGradient::ComponentInterpolation);
QSvgGradientStyle *prop = new QSvgGradientStyle(grad);
parseBaseGradient(node, attributes, prop, handler);
@@ -2783,7 +2784,6 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
nfy = toDouble(fy);
QRadialGradient *grad = new QRadialGradient(ncx, ncy, nr, nfx, nfy);
- grad->setColorAt(qQNaN(), QColor());
grad->setInterpolationMode(QGradient::ComponentInterpolation);
QSvgGradientStyle *prop = new QSvgGradientStyle(grad);
@@ -2929,12 +2929,9 @@ static bool parseStopNode(QSvgStyleProperty *parent,
QGradient *grad = style->qgradient();
offset = qMin(qreal(1), qMax(qreal(0), offset)); // Clamp to range [0, 1]
- QGradientStops stops = grad->stops();
- // Check if the gradient is marked as empty (marked with one single stop at NaN).
- if ((stops.size() == 1) && qIsNaN(stops.at(0).first)) {
- stops.clear();
- grad->setStops(stops);
- } else {
+ QGradientStops stops;
+ if (style->gradientStopsSet()) {
+ stops = grad->stops();
// If the stop offset equals the one previously added, add an epsilon to make it greater.
if (offset <= stops.back().first)
offset = stops.back().first + FLT_EPSILON;
@@ -2950,6 +2947,7 @@ static bool parseStopNode(QSvgStyleProperty *parent,
}
grad->setColorAt(offset, color);
+ style->setGradientStopsSet(true);
if (!colorOK)
style->addResolve(offset);
return true;
diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp
index 389f68f..b065395 100644
--- a/src/svg/qsvgstyle.cpp
+++ b/src/svg/qsvgstyle.cpp
@@ -231,7 +231,7 @@ void QSvgSolidColorStyle::revert(QPainter *p, QSvgExtraStates &)
}
QSvgGradientStyle::QSvgGradientStyle(QGradient *grad)
- : m_gradient(grad)
+ : m_gradient(grad), m_gradientStopsSet(false)
{
}
@@ -256,14 +256,13 @@ void QSvgGradientStyle::apply(QPainter *p, const QRectF &/*rect*/, QSvgNode *, Q
}
// If the gradient is marked as empty, insert transparent black
- QGradientStops stops = m_gradient->stops();
- if (stops.size() == 1 && qIsNaN(stops.at(0).first))
+ if (!m_gradientStopsSet) {
m_gradient->setStops(QGradientStops() << QGradientStop(0.0, QColor(0, 0, 0, 0)));
-
- QGradient gradient = *m_gradient;
+ m_gradientStopsSet = true;
+ }
QBrush brush;
- brush = QBrush(gradient);
+ brush = QBrush(*m_gradient);
if (!m_matrix.isIdentity())
brush.setMatrix(m_matrix);
diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h
index ff4058b..058ba35 100644
--- a/src/svg/qsvgstyle_p.h
+++ b/src/svg/qsvgstyle_p.h
@@ -376,6 +376,16 @@ public:
}
void addResolve(qreal offset);
+
+ bool gradientStopsSet() const
+ {
+ return m_gradientStopsSet;
+ }
+
+ void setGradientStopsSet(bool set)
+ {
+ m_gradientStopsSet = set;
+ }
private:
QGradient *m_gradient;
QList<qreal> m_resolvePoints;
@@ -386,6 +396,7 @@ private:
QSvgTinyDocument *m_doc;
QString m_link;
+ bool m_gradientStopsSet;
};
class QSvgTransformStyle : public QSvgStyleProperty
diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh
index 4c6c431..215b8cb 100755
--- a/src/tools/moc/util/generate.sh
+++ b/src/tools/moc/util/generate.sh
@@ -1,11 +1,7 @@
#!/bin/sh
-p4 edit ../keywords.cpp
-p4 edit ../ppkeywords.cpp
qmake
make
cat licenseheader.txt > ../keywords.cpp
cat licenseheader.txt > ../ppkeywords.cpp
./generate_keywords >> ../keywords.cpp
./generate_keywords preprocessor >> ../ppkeywords.cpp
-p4 revert -a ../keywords.cpp
-p4 revert -a ../ppkeywords.cpp
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
index 990db84..8b061cd 100644
--- a/src/tools/uic/cpp/cppwriteincludes.cpp
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -49,80 +49,58 @@
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>
-QT_BEGIN_NAMESPACE
-
-namespace {
- enum { debugWriteIncludes = 0 };
- enum { warnHeaderGeneration = 0 };
-
-struct StringPair
-{
- const char *key;
- const char *value;
+#include <stdio.h>
- inline bool operator<(const StringPair &b) const { return qstrcmp(key, b.key) < 0; }
-};
+QT_BEGIN_NAMESPACE
+enum { debugWriteIncludes = 0 };
+enum { warnHeaderGeneration = 0 };
-class StringPairs
+struct ClassInfoEntry
{
-public:
- StringPairs(StringPair *begin, int n)
- : m_begin(begin), m_n(n)
- {
- qSort(m_begin, m_begin + n);
- }
-
- const char *searchEntry(const QString &str) const
- {
- QByteArray ba = str.toLatin1();
- const StringPair *begin = m_begin;
- const StringPair *end = m_begin + m_n;
- while (true) {
- int d = (end - begin) / 2;
- if (d == 0)
- return 0;
- const StringPair *mid = begin + d;
- int i = qstrcmp(mid->key, ba.constData());
- if (i == 0)
- return mid->value;
- if (i < 0)
- begin = mid;
- else
- end = mid;
- }
- }
-
-private:
- StringPair *m_begin;
- int m_n;
+ const char *klass;
+ const char *module;
+ const char *header;
};
-
-static StringPair cth[] = {
-#define QT_CLASS_LIB(klass, module, header) { #klass, #module "/" #klass },
+static const ClassInfoEntry qclass_lib_map[] = {
+#define QT_CLASS_LIB(klass, module, header) { #klass, #module, #header },
#include "qclass_lib_map.h"
-#undef QT_CLASS_LIB
-};
-
-static StringPair hth[] = {
-#define QT_CLASS_LIB(klass, module, header) { #header, #module "/" #klass },
-#include "qclass_lib_map.h"
#undef QT_CLASS_LIB
};
-static StringPairs classToHeader(cth, sizeof(cth) / sizeof(cth[0]));
-static StringPairs oldHeaderToHeader(hth, sizeof(hth) / sizeof(hth[0]));
-
-} // namespace anon
-
+// Format a module header as 'QtCore/QObject'
+static inline QString moduleHeader(const QString &module, const QString &header)
+{
+ QString rc = module;
+ rc += QLatin1Char('/');
+ rc += header;
+ return rc;
+}
namespace CPP {
WriteIncludes::WriteIncludes(Uic *uic)
: m_uic(uic), m_output(uic->output()), m_scriptsActivated(false)
{
+ // When possible (no namespace) use the "QtModule/QClass" convention
+ // and create a re-mapping of the old header "qclass.h" to it. Do not do this
+ // for the "Phonon::Someclass" classes, however.
+ const QString namespaceDelimiter = QLatin1String("::");
+ const ClassInfoEntry *classLibEnd = qclass_lib_map + sizeof(qclass_lib_map)/sizeof(ClassInfoEntry);
+ for(const ClassInfoEntry *it = qclass_lib_map; it < classLibEnd; ++it) {
+ const QString klass = QLatin1String(it->klass);
+ const QString module = QLatin1String(it->module);
+ QLatin1String header = QLatin1String(it->header);
+ if (klass.contains(namespaceDelimiter)) {
+ m_classToHeader.insert(klass, moduleHeader(module, header));
+ } else {
+ const QString newHeader = moduleHeader(module, klass);
+ m_classToHeader.insert(klass, newHeader);
+ m_oldHeaderToNewHeader.insert(header, newHeader);
+ }
+ }
}
void WriteIncludes::acceptUI(DomUI *node)
@@ -171,6 +149,9 @@ void WriteIncludes::acceptUI(DomUI *node)
void WriteIncludes::acceptWidget(DomWidget *node)
{
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s '%s'\n", Q_FUNC_INFO, qPrintable(node->attributeClass()));
+
add(node->attributeClass());
TreeWalker::acceptWidget(node);
}
@@ -198,17 +179,17 @@ void WriteIncludes::acceptProperty(DomProperty *node)
void WriteIncludes::insertIncludeForClass(const QString &className, QString header, bool global)
{
- if (debugWriteIncludes) {
- qDebug() << "WriteIncludes::insertIncludeForClass" << className << header << global;
- }
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
do {
if (!header.isEmpty())
break;
- // Known class
- if (const char *p = classToHeader.searchEntry(className)) {
- header = QLatin1String(p);
+ // Known class
+ const StringMap::const_iterator it = m_classToHeader.constFind(className);
+ if (it != m_classToHeader.constEnd()) {
+ header = it.value();
global = true;
break;
}
@@ -245,9 +226,8 @@ void WriteIncludes::insertIncludeForClass(const QString &className, QString head
void WriteIncludes::add(const QString &className, bool determineHeader, const QString &header, bool global)
{
- if (debugWriteIncludes) {
- qDebug() << "WriteIncludes::add" << className << header << global;
- }
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
if (className.isEmpty() || m_knownClasses.contains(className))
return;
@@ -283,7 +263,7 @@ void WriteIncludes::acceptCustomWidget(DomCustomWidget *node)
// custom header unless it is a built-in qt class
QString header;
bool global = false;
- if (!classToHeader.searchEntry(className)) {
+ if (!m_classToHeader.contains(className)) {
global = node->elementHeader()->attributeLocation().toLower() == QLatin1String("global");
header = node->elementHeader()->text();
}
@@ -311,9 +291,8 @@ void WriteIncludes::acceptInclude(DomInclude *node)
void WriteIncludes::insertInclude(const QString &header, bool global)
{
- if (debugWriteIncludes) {
- qDebug() << "WriteIncludes::insertInclude" << header << global;
- }
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s %d\n", Q_FUNC_INFO, qPrintable(header), global);
OrderedSet &includes = global ? m_globalIncludes : m_localIncludes;
if (includes.contains(header))
@@ -328,17 +307,13 @@ void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global)
{
const QChar openingQuote = global ? QLatin1Char('<') : QLatin1Char('"');
const QChar closingQuote = global ? QLatin1Char('>') : QLatin1Char('"');
- const QChar qHeaderStart = QLatin1Char('q');
+ // Check for the old headers 'qslider.h' and replace by 'QtGui/QSlider'
const OrderedSet::const_iterator cend = headers.constEnd();
for (OrderedSet::const_iterator sit = headers.constBegin(); sit != cend; ++sit) {
- QString header = sit.key();
- // Check for the old qslider.h and replace by QtGui/QSlider,
- // but don't do that for phonon headers (volumeslider.h)
- if (header.startsWith(qHeaderStart)) {
- if (const char *p = oldHeaderToHeader.searchEntry(header))
- header = QLatin1String(p);
- }
+ const StringMap::const_iterator hit = m_oldHeaderToNewHeader.constFind(sit.key());
+ const bool mapped = hit != m_oldHeaderToNewHeader.constEnd();
+ const QString header = mapped ? hit.value() : sit.key();
if (!header.trimmed().isEmpty()) {
m_output << "#include " << openingQuote << header << closingQuote << QLatin1Char('\n');
}
diff --git a/src/tools/uic/cpp/cppwriteincludes.h b/src/tools/uic/cpp/cppwriteincludes.h
index 55bd433..8b79041 100644
--- a/src/tools/uic/cpp/cppwriteincludes.h
+++ b/src/tools/uic/cpp/cppwriteincludes.h
@@ -101,6 +101,11 @@ private:
QSet<QString> m_includeBaseNames;
QSet<QString> m_knownClasses;
+
+ typedef QMap<QString, QString> StringMap;
+ StringMap m_classToHeader;
+ StringMap m_oldHeaderToNewHeader;
+
bool m_scriptsActivated;
};
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index ed06006..3d702dd 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -1648,21 +1648,21 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
const QString pixmap = QLatin1String("QPixmap");
m_output << m_indent << "QIcon " << iconName << ";\n";
if (i->hasElementNormalOff())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementNormalOff()->text()) << ", QIcon::Normal, QIcon::Off);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Normal, QIcon::Off);\n";
if (i->hasElementNormalOn())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementNormalOn()->text()) << ", QIcon::Normal, QIcon::On);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Normal, QIcon::On);\n";
if (i->hasElementDisabledOff())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementDisabledOff()->text()) << ", QIcon::Disabled, QIcon::Off);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
if (i->hasElementDisabledOn())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementDisabledOn()->text()) << ", QIcon::Disabled, QIcon::On);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Disabled, QIcon::On);\n";
if (i->hasElementActiveOff())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementActiveOff()->text()) << ", QIcon::Active, QIcon::Off);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Active, QIcon::Off);\n";
if (i->hasElementActiveOn())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementActiveOn()->text()) << ", QIcon::Active, QIcon::On);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Active, QIcon::On);\n";
if (i->hasElementSelectedOff())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementSelectedOff()->text()) << ", QIcon::Selected, QIcon::Off);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Selected, QIcon::Off);\n";
if (i->hasElementSelectedOn())
- m_output << m_indent << iconName << ".addPixmap(" << pixCall(pixmap, i->elementSelectedOn()->text()) << ", QIcon::Selected, QIcon::On);\n";
+ m_output << m_indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), m_dindent) << "), QSize(), QIcon::Selected, QIcon::On);\n";
} else { // pre-4.4 legacy
m_output << m_indent << "const QIcon " << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())<< ";\n";
}
diff --git a/tests/arthur/common/paintcommands.cpp b/tests/arthur/common/paintcommands.cpp
index a72e689..6ab71f8 100644
--- a/tests/arthur/common/paintcommands.cpp
+++ b/tests/arthur/common/paintcommands.cpp
@@ -1886,7 +1886,6 @@ void PaintCommands::command_setBrushOrigin(QRegExp re)
/***************************************************************************************************/
void PaintCommands::command_brushTranslate(QRegExp re)
{
-#if QT_VERSION > 0x040200
QStringList caps = re.capturedTexts();
double dx = convertToDouble(caps.at(1));
double dy = convertToDouble(caps.at(2));
@@ -1899,13 +1898,11 @@ void PaintCommands::command_brushTranslate(QRegExp re)
brush_matrix.translate(dx, dy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
-#endif
}
/***************************************************************************************************/
void PaintCommands::command_brushScale(QRegExp re)
{
-#if QT_VERSION > 0x040200
QStringList caps = re.capturedTexts();
double sx = convertToDouble(caps.at(1));
double sy = convertToDouble(caps.at(2));
@@ -1918,13 +1915,11 @@ void PaintCommands::command_brushScale(QRegExp re)
brush_matrix.scale(sx, sy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
-#endif
}
/***************************************************************************************************/
void PaintCommands::command_brushRotate(QRegExp re)
{
-#if QT_VERSION > 0x040200
QStringList caps = re.capturedTexts();
double rot = convertToDouble(caps.at(1));
@@ -1936,13 +1931,11 @@ void PaintCommands::command_brushRotate(QRegExp re)
brush_matrix.rotate(rot);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
-#endif
}
/***************************************************************************************************/
void PaintCommands::command_brushShear(QRegExp re)
{
-#if QT_VERSION > 0x040200
QStringList caps = re.capturedTexts();
double sx = convertToDouble(caps.at(1));
double sy = convertToDouble(caps.at(2));
@@ -1955,7 +1948,6 @@ void PaintCommands::command_brushShear(QRegExp re)
brush_matrix.shear(sx, sy);
new_brush.setTransform(brush_matrix);
m_painter->setBrush(new_brush);
-#endif
}
/***************************************************************************************************/
@@ -2326,10 +2318,8 @@ void PaintCommands::command_gradient_setLinear(QRegExp re)
lg.setSpread(m_gradientSpread);
lg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(lg);
-#if QT_VERSION > 0x040200
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
-#endif
m_painter->setBrush(brush);
}
@@ -2375,10 +2365,8 @@ void PaintCommands::command_gradient_setRadial(QRegExp re)
rg.setSpread(m_gradientSpread);
rg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(rg);
-#if QT_VERSION > 0x040200
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
-#endif
m_painter->setBrush(brush);
}
@@ -2400,10 +2388,8 @@ void PaintCommands::command_gradient_setConical(QRegExp re)
cg.setSpread(m_gradientSpread);
cg.setCoordinateMode(m_gradientCoordinate);
QBrush brush(cg);
-#if QT_VERSION > 0x040200
QTransform brush_matrix = m_painter->brush().transform();
brush.setTransform(brush_matrix);
-#endif
m_painter->setBrush(brush);
}
@@ -2448,7 +2434,6 @@ void PaintCommands::command_surface_begin(QRegExp re)
m_surface_painter = m_painter;
-#if QT_VERSION > 0x040200
if (m_type == OpenGLType || m_type == OpenGLPBufferType) {
#ifndef QT_NO_OPENGL
m_surface_pbuffer = new QGLPixelBuffer(qRound(w), qRound(h));
@@ -2461,9 +2446,7 @@ void PaintCommands::command_surface_begin(QRegExp re)
m_surface_pixmap.fill(Qt::transparent);
m_painter = new QPainter(&m_surface_pixmap);
#endif
- } else
-#endif
- {
+ } else {
m_surface_image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32_Premultiplied);
m_surface_image.fill(0);
m_painter = new QPainter(&m_surface_image);
diff --git a/tests/arthur/common/qengines.cpp b/tests/arthur/common/qengines.cpp
index 46f4e6b..9cd2389 100644
--- a/tests/arthur/common/qengines.cpp
+++ b/tests/arthur/common/qengines.cpp
@@ -243,11 +243,7 @@ void GLEngine::prepare(const QSize &_size, const QColor &color)
size = _size;
fillColor = color;
if (usePixelBuffers) {
-#if (QT_VERSION < 0x040200) && defined(Q_WS_MAC)
- pbuffer = new QGLPixelBuffer(QSize(512, 512), QGLFormat(QGL::SampleBuffers));
-#else
pbuffer = new QGLPixelBuffer(size, QGLFormat(QGL::SampleBuffers));
-#endif
} else {
widget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
widget->setAutoFillBackground(false);
diff --git a/tests/arthur/data/qps/primitives.qps b/tests/arthur/data/qps/primitives.qps
index dcb6516..c4cc92c 100644
--- a/tests/arthur/data/qps/primitives.qps
+++ b/tests/arthur/data/qps/primitives.qps
@@ -177,3 +177,22 @@ repeat_block drawShapes
setPen black 4
translate 75 0
repeat_block drawShapes
+
+resetMatrix
+setRenderHint Antialiasing off
+setPen nopen
+translate 550 100
+setBrush #7f7f7fff
+drawRect -0.5 -0.5 21 21
+setBrush red
+drawEllipse 0 0 20 20
+setBrush nobrush
+setPen black
+drawEllipse 0 0 20 20
+
+translate 25 0
+setPen nopen
+setBrush #7f7f7fff
+drawRect 0 0 20 20
+setBrush red
+drawEllipse 0 0 20 20
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index ee44a62..f8f15a3 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -273,7 +273,6 @@ SUBDIRS += bic \
qspinbox \
qsplitter \
qsql \
- qsqlbatch \
qsqldatabase \
qsqlerror \
qsqlfield \
@@ -414,8 +413,7 @@ SUBDIRS += checkxmlfiles \
xmlpatternsdiagnosticsts \
xmlpatternsview \
xmlpatternsxqts \
- xmlpatternsxslts \
- xmlpatterns
+ xmlpatternsxslts
xmlpatternsdiagnosticsts.depends = xmlpatternsxqts
xmlpatternsview.depends = xmlpatternsxqts
diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp
index e0f42f0..181c275 100644
--- a/tests/auto/bic/tst_bic.cpp
+++ b/tests/auto/bic/tst_bic.cpp
@@ -195,29 +195,10 @@ void tst_Bic::sizesAndVTables_data()
&& archFileName420.isEmpty())
QSKIP("No reference files found for this platform", SkipAll);
-#if QT_VERSION >= 0x040100
bool isPatchRelease400 = false;
-#else
- bool isPatchRelease400 = true;
-#endif
-
-#if QT_VERSION >= 0x040200
bool isPatchRelease410 = false;
-#else
- bool isPatchRelease410 = true;
-#endif
-
-#if QT_VERSION >= 0x040300
bool isPatchRelease420 = false;
-#else
- bool isPatchRelease420 = true;
-#endif
-
-#if QT_VERSION >= 0x040400
bool isPatchRelease430 = false;
-#else
- bool isPatchRelease430 = true;
-#endif
QTest::addColumn<QString>("oldLib");
QTest::addColumn<bool>("isPatchRelease");
diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp
index 6d3d1df..c05d8da 100644
--- a/tests/auto/collections/tst_collections.cpp
+++ b/tests/auto/collections/tst_collections.cpp
@@ -161,9 +161,7 @@ private slots:
void q_init();
void pointersize();
void containerInstantiation();
-#if QT_VERSION >= 0x040101
void qtimerList();
-#endif
void containerTypedefs();
void forwardDeclared();
};
@@ -1907,11 +1905,9 @@ void tst_Collections::map()
i.toFront();
while(i.hasNext()) {
sum += i.next().value();
-#if QT_VERSION >= 0x040100
i.setValue(10);
i.value() += 22;
QVERIFY(i.value() == 32);
-#endif
}
QVERIFY(sum == 11);
}
@@ -2870,10 +2866,8 @@ void tst_Collections::javaStyleIterators()
while (i.hasPrevious()) {
i.previous();
QVERIFY(i.value().isEmpty());
-#if QT_VERSION >= 0x040100
i.value() = "x";
QCOMPARE(i.value(), QString("x"));
-#endif
}
}
@@ -3355,7 +3349,6 @@ void tst_Collections::containerInstantiation()
instantiateRandomAccess<Stack, EqualsComparable>();
}
-#if QT_VERSION >= 0x040101
void tst_Collections::qtimerList()
{
QList<double> foo;
@@ -3378,7 +3371,6 @@ void tst_Collections::qtimerList()
}
QFAIL("QList preallocates too much memory");
}
-#endif
template <typename Container>
void testContainerTypedefs(Container container)
@@ -3387,11 +3379,11 @@ void testContainerTypedefs(Container container)
{ typedef typename Container::value_type Foo; }
{ typedef typename Container::iterator Foo; }
{ typedef typename Container::const_iterator Foo; }
- { typedef typename Container::reference Foo; }
- { typedef typename Container::const_reference Foo; }
- { typedef typename Container::pointer Foo; }
- { typedef typename Container::difference_type Foo; }
- { typedef typename Container::size_type Foo; }
+ { typedef typename Container::reference Foo; }
+ { typedef typename Container::const_reference Foo; }
+ { typedef typename Container::pointer Foo; }
+ { typedef typename Container::difference_type Foo; }
+ { typedef typename Container::size_type Foo; }
}
template <typename Container>
@@ -3403,11 +3395,11 @@ void testPairAssociativeContainerTypedefs(Container container)
// { typedef typename Container::value_type Foo; }
// { typedef typename Container::const_iterator Foo; }
// { typedef typename Container::reference Foo; }
-// { typedef typename Container::const_reference Foo; }
-// { typedef typename Container::pointer Foo; }
+// { typedef typename Container::const_reference Foo; }
+// { typedef typename Container::pointer Foo; }
- { typedef typename Container::difference_type Foo; }
- { typedef typename Container::size_type Foo; }
+ { typedef typename Container::difference_type Foo; }
+ { typedef typename Container::size_type Foo; }
{ typedef typename Container::iterator Foo; }
{ typedef typename Container::key_type Foo; }
{ typedef typename Container::mapped_type Foo; }
@@ -3422,11 +3414,11 @@ void testSetContainerTypedefs(Container container)
Q_UNUSED(container)
{ typedef typename Container::iterator Foo; }
{ typedef typename Container::const_iterator Foo; }
- { typedef typename Container::reference Foo; }
- { typedef typename Container::const_reference Foo; }
- { typedef typename Container::pointer Foo; }
- { typedef typename Container::difference_type Foo; }
- { typedef typename Container::size_type Foo; }
+ { typedef typename Container::reference Foo; }
+ { typedef typename Container::const_reference Foo; }
+ { typedef typename Container::pointer Foo; }
+ { typedef typename Container::difference_type Foo; }
+ { typedef typename Container::size_type Foo; }
{ typedef typename Container::key_type Foo; }
}
@@ -3450,7 +3442,7 @@ void tst_Collections::containerTypedefs()
}
#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
-class Key1
+class Key1
{};
class T1
{};
diff --git a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp
index 232af55..1f5f479 100644
--- a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp
+++ b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp
@@ -173,9 +173,7 @@ void tst_CompilerWarnings::warnings()
<< "-Wno-long-long" << "-Wshadow" << "-Wpacked" << "-Wunreachable-code"
<< "-Wundef" << "-Wchar-subscripts" << "-Wformat-nonliteral" << "-Wformat-security"
<< "-Wcast-align"
-#if QT_VERSION >= 0x040100
<< "-Wfloat-equal"
-#endif
<< "-o" << tmpFile
<< tmpSourceFile;
#elif defined(Q_CC_XLC)
diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp
index 96589b7..1b113b2 100644
--- a/tests/auto/mediaobject/tst_mediaobject.cpp
+++ b/tests/auto/mediaobject/tst_mediaobject.cpp
@@ -349,6 +349,18 @@ void tst_MediaObject::_pausePlayback()
void tst_MediaObject::initTestCase()
{
QCoreApplication::setApplicationName("tst_MediaObject");
+ m_stateChangedSignalSpy = 0;
+ m_media = 0;
+
+#ifdef Q_OS_WINCE
+ QString pluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath);
+#ifdef DEBUG
+ QVERIFY(QFile::exists(pluginsPath + "/phonon_backend/phonon_waveoutd4.dll") || QFile::exists(pluginsPath + "/phonon_backend/phonon_phonon_ds9d4.dll"));
+#else
+ QVERIFY(QFile::exists(pluginsPath + "/phonon_backend/phonon_waveout4.dll") || QFile::exists(pluginsPath + "/phonon_backend/phonon_phonon_ds94.dll"));
+#endif
+#endif
+
m_url = qgetenv("PHONON_TESTURL");
m_media = new MediaObject(this);
@@ -787,7 +799,7 @@ void tst_MediaObject::setMediaAndPlay()
QSignalSpy totalTimeChangedSignalSpy(m_media, SIGNAL(totalTimeChanged(qint64)));
QVERIFY(m_media->currentSource().type() != MediaSource::Invalid);
Phonon::State state = m_media->state();
- QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState);
+ QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState || Phonon::PausedState);
m_media->setCurrentSource(m_url);
// before calling play() we better make sure that if play() finishes very fast that we don't get
// called again
@@ -856,8 +868,10 @@ void tst_MediaObject::testPlayBeforeFinish()
void tst_MediaObject::cleanupTestCase()
{
- delete m_stateChangedSignalSpy;
- delete m_media;
+ if (m_stateChangedSignalSpy)
+ delete m_stateChangedSignalSpy;
+ if (m_media)
+ delete m_media;
#ifdef Q_OS_WINCE
QTest::qWait(200);
#endif
diff --git a/tests/auto/moc/forgotten-qinterface.h b/tests/auto/moc/forgotten-qinterface.h
index a11793b..370a3d0 100644
--- a/tests/auto/moc/forgotten-qinterface.h
+++ b/tests/auto/moc/forgotten-qinterface.h
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include <QObject>
+
struct MyInterface
{
virtual ~MyInterface() {}
diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp
index 39f4f23..afb31f6 100644
--- a/tests/auto/moc/tst_moc.cpp
+++ b/tests/auto/moc/tst_moc.cpp
@@ -151,7 +151,6 @@ public slots:
Q_DECLARE_METATYPE(MyStruct)
Q_DECLARE_METATYPE(MyStruct*)
-#if QT_VERSION >= 0x040200
namespace myNS {
struct Points
{
@@ -161,7 +160,6 @@ namespace myNS {
}
Q_DECLARE_METATYPE(myNS::Points)
-#endif
class TestClassinfoWithEscapes: public QObject
{
@@ -195,10 +193,7 @@ class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(My
public DONT_CONFUSE_MOC_EVEN_MORE(MyStruct2, dummy, ignored)
{
Q_OBJECT
-#if QT_VERSION >= 0x040101
Q_CLASSINFO("help", QT_TR_NOOP("Opening this will let you configure something"))
-#endif
-#if QT_VERSION >= 0x040102
Q_PROPERTY(short int shortIntProperty READ shortIntProperty)
Q_PROPERTY(unsigned short int unsignedShortIntProperty READ unsignedShortIntProperty)
Q_PROPERTY(signed short int signedShortIntProperty READ signedShortIntProperty)
@@ -206,10 +201,7 @@ class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(My
Q_PROPERTY(unsigned long int unsignedLongIntProperty READ unsignedLongIntProperty)
Q_PROPERTY(signed long int signedLongIntProperty READ signedLongIntProperty)
Q_PROPERTY(long double longDoubleProperty READ longDoubleProperty)
-#endif
-#if QT_VERSION >= 0x040200
Q_PROPERTY(myNS::Points points READ points WRITE setPoints)
-#endif
Q_CLASSINFO("Multi"
"line",
@@ -294,9 +286,7 @@ private slots:
#ifndef NOLONGLONG
void slotWithULongLong(unsigned long long) {}
-#if QT_VERSION >= 0x040101
void slotWithULongLongP(unsigned long long*) {}
-#endif
void slotWithULong(unsigned long) {}
void slotWithLongLong(long long) {}
void slotWithLong(long) {}
@@ -304,9 +294,7 @@ private slots:
void slotWithColonColonType(::Int::Type) {}
-#if QT_VERSION >= 0x040101
TestClass &slotWithReferenceReturnType() { return *this; }
-#endif
#if (0 && 1) || 1
void expressionEvaluationShortcut1() {}
@@ -321,7 +309,6 @@ public slots:
void slotWithNamedArray(const double namedArray[3]) {}
void slotWithMultiArray(const double[3][4]) {}
-#if QT_VERSION >= 0x040102
short int shortIntProperty() { return 0; }
unsigned short int unsignedShortIntProperty() { return 0; }
signed short int signedShortIntProperty() { return 0; }
@@ -329,12 +316,9 @@ public slots:
unsigned long int unsignedLongIntProperty() { return 0; }
signed long int signedLongIntProperty() { return 0; }
long double longDoubleProperty() { return 0.0; }
-#endif
-#if QT_VERSION >= 0x040200
myNS::Points points() { return m_points; }
void setPoints(myNS::Points points) { m_points = points; }
-#endif
signals:
void signalWithArray(const double[3]);
@@ -384,10 +368,8 @@ public:
public slots:
void slotWithVoidStar(void *) {}
-#if QT_VERSION >= 0x040200
private:
myNS::Points m_points;
-#endif
private slots:
inline virtual void blub1() {}
@@ -466,6 +448,8 @@ public:
inline tst_Moc() {}
private slots:
+ void initTestCase();
+
void slotWithException() throw(MyStruct);
void dontStripNamespaces();
void oldStyleCasts();
@@ -519,8 +503,28 @@ private:
bool user2() { return false; };
bool user3() { return false; };
bool userFunction(){ return false; };
+
+private:
+ QString qtIncludePath;
};
+void tst_Moc::initTestCase()
+{
+#if defined(Q_OS_UNIX)
+ QProcess proc;
+ proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS");
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray output = proc.readAllStandardOutput();
+ QVERIFY(!output.isEmpty());
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+ qtIncludePath = QString::fromLocal8Bit(output).trimmed();
+ QFileInfo fi(qtIncludePath);
+ QVERIFY(fi.exists());
+ QVERIFY(fi.isDir());
+#endif
+}
+
void tst_Moc::slotWithException() throw(MyStruct)
{
// be happy
@@ -552,8 +556,6 @@ void tst_Moc::oldStyleCasts()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
proc.start("moc", QStringList(srcify("/oldstyle-casts.h")));
QVERIFY(proc.waitForFinished());
@@ -564,7 +566,7 @@ void tst_Moc::oldStyleCasts()
QStringList args;
args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
- << "-I" << qgetenv("QTDIR") + "/include" << "-o" << "/dev/null" << "-";
+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-";
proc.start("gcc", args);
QVERIFY(proc.waitForStarted());
proc.write(mocOut);
@@ -584,8 +586,6 @@ void tst_Moc::warnOnExtraSignalSlotQualifiaction()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
proc.start("moc", QStringList(srcify("extraqualification.h")));
QVERIFY(proc.waitForFinished());
@@ -610,10 +610,8 @@ void tst_Moc::uLongLong()
QVERIFY(idx != -1);
idx = mobj->indexOfSlot("slotWithULongLong(unsigned long long)");
QVERIFY(idx != -1);
-#if QT_VERSION >= 0x040101
idx = mobj->indexOfSlot("slotWithULongLongP(unsigned long long*)");
QVERIFY(idx != -1);
-#endif
idx = mobj->indexOfSlot("slotWithLong(long)");
QVERIFY(idx != -1);
@@ -630,8 +628,6 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
proc.setWorkingDirectory(QString(SRCDIR) + "/task71021");
proc.start("moc", QStringList("../Header"));
@@ -643,7 +639,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
QStringList args;
args << "-c" << "-x" << "c++" << "-I" << ".."
- << "-I" << qgetenv("QTDIR") + "/include" << "-o" << "/dev/null" << "-";
+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-";
proc.start("gcc", args);
QVERIFY(proc.waitForStarted());
proc.write(mocOut);
@@ -691,22 +687,14 @@ void tst_Moc::supportConstSignals()
void tst_Moc::task87883()
{
-#if QT_VERSION >= 0x040101
QVERIFY(Task87883::staticMetaObject.className());
-#else
- QSKIP("Fixed in >= 4.1.1", SkipAll);
-#endif
}
#include "c-comments.h"
void tst_Moc::multilineComments()
{
-#if QT_VERSION >= 0x040101
QVERIFY(IfdefedClass::staticMetaObject.className());
-#else
- QSKIP("Fixed in >= 4.1.1", SkipAll);
-#endif
}
void tst_Moc::classinfoWithEscapes()
@@ -848,10 +836,11 @@ void tst_Moc::warnOnMultipleInheritance()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
- proc.start("moc", QStringList(srcify("warn-on-multiple-qobject-subclasses.h")));
+ QStringList args;
+ args << "-I" << qtIncludePath + "/QtGui"
+ << srcify("warn-on-multiple-qobject-subclasses.h");
+ proc.start("moc", args);
QVERIFY(proc.waitForFinished());
QCOMPARE(proc.exitCode(), 0);
QByteArray mocOut = proc.readAllStandardOutput();
@@ -870,17 +859,18 @@ void tst_Moc::forgottenQInterface()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
- proc.start("moc", QStringList(srcify("forgotten-qinterface.h")));
+ QStringList args;
+ args << "-I" << qtIncludePath + "/QtCore"
+ << srcify("forgotten-qinterface.h");
+ proc.start("moc", args);
QVERIFY(proc.waitForFinished());
QCOMPARE(proc.exitCode(), 0);
QByteArray mocOut = proc.readAllStandardOutput();
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocWarning, QString(SRCDIR) +
- QString("/forgotten-qinterface.h:53: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
+ QString("/forgotten-qinterface.h:55: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
#else
QSKIP("Only tested on linux/gcc", SkipAll);
#endif
@@ -951,8 +941,6 @@ void tst_Moc::frameworkSearchPath()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_UNIX)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QStringList args;
args << "-F" << srcify(".")
<< srcify("interface-from-framework.h")
@@ -991,8 +979,6 @@ void tst_Moc::templateGtGt()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
proc.start("moc", QStringList(srcify("template-gtgt.h")));
QVERIFY(proc.waitForFinished());
@@ -1009,8 +995,6 @@ void tst_Moc::templateGtGt()
void tst_Moc::defineMacroViaCmdline()
{
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
QStringList args;
@@ -1099,8 +1083,6 @@ void tst_Moc::warnOnPropertyWithoutREAD()
QSKIP("Not tested when cross-compiled", SkipAll);
#endif
#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
- QVERIFY(!qgetenv("QTDIR").isNull());
-
QProcess proc;
proc.start("moc", QStringList(srcify("warn-on-property-without-read.h")));
QVERIFY(proc.waitForFinished());
diff --git a/tests/auto/q3accel/tst_q3accel.cpp b/tests/auto/q3accel/tst_q3accel.cpp
index c2ba9dd..7b1c8ae 100644
--- a/tests/auto/q3accel/tst_q3accel.cpp
+++ b/tests/auto/q3accel/tst_q3accel.cpp
@@ -142,10 +142,8 @@ void tst_Q3Accel::initTestCase()
edit->setObjectName("test_edit");
connect( accel1, SIGNAL(activated(int)), this, SLOT(accelTrig1()) );
connect( accel2, SIGNAL(activated(int)), this, SLOT(accelTrig2()) );
-#if QT_VERSION >= 0x30100
connect( accel1, SIGNAL(activatedAmbiguously(int)), this, SLOT(ambig1()) );
connect( accel2, SIGNAL(activatedAmbiguously(int)), this, SLOT(ambig2()) );
-#endif
mainW->setCentralWidget( edit );
connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)),
this, SLOT(statusMessage(const QString&)) );
@@ -160,11 +158,9 @@ int tst_Q3Accel::toButtons( int key )
result |= Qt::ShiftModifier;
if ( key & Qt::CTRL )
result |= Qt::ControlModifier;
-#if QT_VERSION >= 0x30100
- if ( key & Qt::META )
+ if ( key & Qt::META )
result |= Qt::MetaModifier;
-#endif
- if ( key & Qt::ALT )
+ if ( key & Qt::ALT )
result |= Qt::AltModifier;
return result;
}
@@ -185,7 +181,6 @@ void tst_Q3Accel::defElements()
QTest::addColumn<int>("theResult");
}
-#if QT_VERSION >= 0x30100
void tst_Q3Accel::number()
{
testElement();
@@ -369,34 +364,17 @@ void tst_Q3Accel::number_data()
int(Qt::Key_Aring)
UNICODE_ACCEL + int(Qt::Key_K)
*/
- /* The #ifdefs for Qt4 are there, because accelerators are always case insensitive in Qt4.
- It was not wise to differentiate between ASCII (where accelerators where case insensitive) and all other
- unicode chars in 3.x.
- */
QTest::newRow( "N06 - sA1" ) << int(SetupAccel) << int(Accel1) << QString("")
<< int(Qt::Key_aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
-#if QT_VERSION < 0x040000
- QTest::newRow( "N07 - sA2" ) << int(SetupAccel) << int(Accel2) << QString("")
- << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
-#endif
QTest::newRow( "N08 - sA2" ) << int(SetupAccel) << int(Accel1) << QString("")
<< int(Qt::UNICODE_ACCEL) + int(Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
QTest::newRow( "N:int(Qt::Key_aring)" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#if QT_VERSION < 0x040000
- QTest::newRow( "N:int(Qt::Key_Aring)" ) << int(TestAccel) << int(NoWidget) << QString("")
- << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel2Triggered);
-#endif
QTest::newRow( "N:int(Qt::Key_aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_unknown) << 0xE5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#if QT_VERSION < 0x040000
- QTest::newRow( "N:int(Qt::Key_Aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
- << int(Qt::Key_unknown) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel2Triggered);
-#else
QTest::newRow( "N:int(Qt::Key_Aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_unknown) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#endif
QTest::newRow( "N:UNICODE_ACCEL + int(Qt::Key_K)" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::UNICODE_ACCEL) + int(Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
@@ -615,28 +593,15 @@ void tst_Q3Accel::text_data()
/* see comments above on the #ifdef'ery */
QTest::newRow( "T06 - sA1" ) << int(SetupAccel) << int(Accel1) << QString("\x0E5")
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
-#if QT_VERSION < 0x040000
- QTest::newRow( "T07 - sA2" ) << int(SetupAccel) << int(Accel2) << QString("\x0C5")
- << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
-#endif
QTest::newRow( "T08 - sA2" ) << int(SetupAccel) << int(Accel1) << QString("K")
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(NoResult);
QTest::newRow( "T:int(Qt::Key_aring)" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#if QT_VERSION < 0x040000
- QTest::newRow( "T:int(Qt::Key_Aring)" ) << int(TestAccel) << int(NoWidget) << QString("")
- << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel2Triggered);
-#endif
QTest::newRow( "T:int(Qt::Key_aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_unknown) << 0xE5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#if QT_VERSION < 0x040000
- QTest::newRow( "T:int(Qt::Key_Aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
- << int(Qt::Key_unknown) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel2Triggered);
-#else
QTest::newRow( "T:int(Qt::Key_Aring) - Text Form" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::Key_unknown) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
-#endif
QTest::newRow( "T:UNICODE_ACCEL + int(Qt::Key_K)" ) << int(TestAccel) << int(NoWidget) << QString("")
<< int(Qt::UNICODE_ACCEL) + int(Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << int(Accel1Triggered);
@@ -986,11 +951,7 @@ void tst_Q3Accel::sendKeyEvents( int k1, QChar c1, int k2, QChar c2, int k3, QCh
k2 &= ~Qt::MODIFIER_MASK;
k3 &= ~Qt::MODIFIER_MASK;
k4 &= ~Qt::MODIFIER_MASK;
-#if QT_VERSION < 0x040000
- QKeyEvent ke( QEvent::Accel, k1, k1, b1, QString(c1) );
-#else
QKeyEvent ke( QEvent::Accel, k1, (Qt::KeyboardModifiers)b1, QString(c1) );
-#endif
QApplication::sendEvent( mainW, &ke );
if ( k2 ) {
QKeyEvent ke( QEvent::Accel, k2, k2, b2, QString(c2) );
@@ -1006,48 +967,5 @@ void tst_Q3Accel::sendKeyEvents( int k1, QChar c1, int k2, QChar c2, int k3, QCh
}
}
-// ----------------------------------------------------------------------------
-// ----------------------------------------------------------------------------
-
-#else // For Qt < 3.1
-void tst_Q3Accel::number_data()
-{
- QTest::addColumn<int>("bogus");
- QTest::newRow( "b01" ) << 0;
-}
-
-void tst_Q3Accel::number()
-{
- QSKIP( "Accel test for Qt < 3.1 not implemented", SkipAll);
-}
-
-void tst_Q3Accel::text_data()
-{
- QTest::addColumn<int>("bogus");
- QTest::newRow( "b02" ) << 0;
-}
-
-void tst_Q3Accel::text()
-{
- QSKIP( "Accel test for Qt < 3.1 not implemented", SkipAll);
-}
-void tst_Q3Accel::disabledItems()
-{
- QSKIP( "Accel test for Qt < 3.1 not implemented", SkipAll);
-}
-void tst_Q3Accel::ambiguousItems()
-{
- QSKIP( "Amibguous signals non-existant in Qt < 3.1", SkipAll);
-}
-void tst_Q3Accel::unicodeCompare()
-{
- QSKIP( "Accel test for Qt < 3.1 not implemented", SkipAll);
-}
-void tst_Q3Accel::unicodeCompose()
-{
- QSKIP( "Unicode composing non-existant in Qt < 3.1", SkipAll);
-}
-#endif // QT_VERSION >= 0x30100
-
QTEST_MAIN(tst_Q3Accel)
#include "tst_q3accel.moc"
diff --git a/tests/auto/q3cstring/tst_q3cstring.cpp b/tests/auto/q3cstring/tst_q3cstring.cpp
index f9bdf6b..60a66a9 100644
--- a/tests/auto/q3cstring/tst_q3cstring.cpp
+++ b/tests/auto/q3cstring/tst_q3cstring.cpp
@@ -69,8 +69,6 @@ private slots:
void replace_uint_uint();
void replace_string_data();
void replace_string();
- void replace_regexp_data();
- void replace_regexp();
void remove_uint_uint_data();
void remove_uint_uint();
void prepend();
@@ -132,11 +130,6 @@ void tst_Q3CString::remove_string_data()
replace_string_data();
}
-void tst_Q3CString::remove_regexp_data()
-{
- replace_regexp_data();
-}
-
void tst_Q3CString::length_data()
{
QTest::addColumn<Q3CString>("s1");
@@ -202,9 +195,6 @@ void tst_Q3CString::replace_string_data()
QTest::newRow( "rem13" ) << Q3CString("") << Q3CString("A") << Q3CString(0) << Q3CString("");
QTest::newRow( "rem14" ) << Q3CString(0) << Q3CString("A") << Q3CString("") << Q3CString(0);
QTest::newRow( "rem15" ) << Q3CString(0) << Q3CString("A") << Q3CString(0) << Q3CString(0);
-#if QT_VERSION < 0x040000
- QTest::newRow( "rem16" ) << Q3CString(0) << Q3CString("") << Q3CString("A") << Q3CString(0);
-#endif
QTest::newRow( "rem17" ) << Q3CString(0) << Q3CString("") << Q3CString("") << Q3CString(0);
// ### how should the one below behave in Q3CString????
// QTest::newRow( "rem18" ) << Q3CString("") << Q3CString(0) << Q3CString("A") << Q3CString("A");
@@ -216,7 +206,7 @@ void tst_Q3CString::replace_string_data()
QTest::newRow( "rep03" ) << Q3CString("") << Q3CString("") << Q3CString("X") << Q3CString("X");
}
-void tst_Q3CString::replace_regexp_data()
+void tst_Q3CString::remove_regexp_data()
{
QTest::addColumn<Q3CString>("string");
QTest::addColumn<Q3CString>("regexp");
@@ -224,20 +214,16 @@ void tst_Q3CString::replace_regexp_data()
QTest::addColumn<Q3CString>("result");
QTest::newRow( "rem00" ) << Q3CString("alpha") << Q3CString("a+") << Q3CString("") << Q3CString("lph");
-#if QT_VERSION >= 0x030100
QTest::newRow( "rem01" ) << Q3CString("banana") << Q3CString("^.a") << Q3CString("") << Q3CString("nana");
-#endif
QTest::newRow( "rem02" ) << Q3CString("") << Q3CString("^.a") << Q3CString("") << Q3CString("");
QTest::newRow( "rem03" ) << Q3CString("") << Q3CString("^.a") << Q3CString(0) << Q3CString("");
QTest::newRow( "rem04" ) << Q3CString(0) << Q3CString("^.a") << Q3CString("") << Q3CString(0);
QTest::newRow( "rem05" ) << Q3CString(0) << Q3CString("^.a") << Q3CString(0) << Q3CString(0);
-#if QT_VERSION >= 0x030100
QTest::newRow( "rep00" ) << Q3CString("A <i>bon mot</i>.") << Q3CString("<i>([^<]*)</i>") << Q3CString("\\emph{\\1}") << Q3CString("A \\emph{bon mot}.");
QTest::newRow( "rep01" ) << Q3CString("banana") << Q3CString("^.a()") << Q3CString("\\1") << Q3CString("nana");
QTest::newRow( "rep02" ) << Q3CString("banana") << Q3CString("(ba)") << Q3CString("\\1X\\1") << Q3CString("baXbanana");
QTest::newRow( "rep03" ) << Q3CString("banana") << Q3CString("(ba)(na)na") << Q3CString("\\2X\\1") << Q3CString("naXba");
-#endif
}
void tst_Q3CString::length()
@@ -364,11 +350,7 @@ void tst_Q3CString::acc_01()
QCOMPARE('X'+a,(Q3CString)"XABC");
a = (const char*)0;
QVERIFY(a.isNull());
-#if QT_VERSION < 0x040000
- QVERIFY((const char*)a==0);
-#else
QVERIFY(*((const char *)a) == 0);
-#endif
{
QFile f("COMPARE.txt");
@@ -420,11 +402,7 @@ void tst_Q3CString::constructor()
QCOMPARE(a,ca);
QVERIFY(a.isNull());
-#if QT_VERSION < 0x040000
- QVERIFY(a != (Q3CString)"");
-#else
QVERIFY(a == Q3CString(""));
-#endif
QCOMPARE(b,cb);
QCOMPARE(c,cc);
QCOMPARE(d,(Q3CString)"String D");
@@ -509,18 +487,6 @@ void tst_Q3CString::find()
//QCOMPARE(a.find('G',-1),14); // -ve does what? Parameter should be uint?
//QCOMPARE(a.find('G',-2),11); // -ve does what? Parameter should be uint?
QCOMPARE(a.find('f'),10);
-#if QT_VERSION < 0x040000
- // case sensitive find has been removed in 4.0
- QCOMPARE(a.find('f',0,FALSE),5);
- QCOMPARE(a.find('g',0,TRUE),-1);
- QCOMPARE(a.find("fgh",0,FALSE),5);
- QCOMPARE(a.find("fgh",0,TRUE),-1);
- QCOMPARE(a.find("EFG",5,TRUE),12);
- QCOMPARE(a.find("EFG",5,FALSE),9);
- QCOMPARE(a.find("EFG",4,TRUE),4);
- QCOMPARE(a.find("EfG",4,FALSE),4);
- QCOMPARE(a.find("EfG",4,TRUE),9);
-#endif
// QCOMPARE(a.find("efg",-1,FALSE),12); // -ve does what? Parameter should be uint?
// QCOMPARE(a.find("efg",-2,FALSE),12); // -ve does what? Parameter should be uint?
// QCOMPARE(a.find("efg",-3,FALSE),12); // -ve does what? Parameter should be uint?
@@ -544,14 +510,6 @@ void tst_Q3CString::findRev()
QCOMPARE(a.findRev('B'),1);
QCOMPARE(a.findRev('B',1),1);
QCOMPARE(a.findRev('B',0),-1);
-#if QT_VERSION < 0x040000
- QCOMPARE(a.findRev("efg",99,FALSE),-1);
-// QCOMPARE(a.findRev("efg",15,FALSE),-1);
- QCOMPARE(a.findRev("efg",16,FALSE),-1);
- QCOMPARE(a.findRev("efg",14,FALSE),12);
- QCOMPARE(a.findRev("efg",12,FALSE),12);
- QCOMPARE(a.findRev("efg",11,FALSE),9);
-#endif
// QCOMPARE(a.findRev(QRegExp("[EFG][EFG]"),14),13);
// QCOMPARE(a.findRev(QRegExp("[EFG][EFG]"),11),11);
}
@@ -560,15 +518,6 @@ void tst_Q3CString::contains()
{
Q3CString a;
a="ABCDEFGHIEfGEFG"; // 15 chars
-#if QT_VERSION < 0x040000
- QCOMPARE(a.contains('A'),1);
- QCOMPARE(a.contains('Z'),0);
- QCOMPARE(a.contains('E'),3);
- QCOMPARE(a.contains('F'),2);
- QCOMPARE(a.contains('F',FALSE),3);
- QCOMPARE(a.contains("FG"),2);
- QCOMPARE(a.contains("FG",FALSE),3);
-#else
QVERIFY(a.contains('A'));
QVERIFY(!a.contains('Z'));
QVERIFY(a.contains('E'));
@@ -579,7 +528,6 @@ void tst_Q3CString::contains()
QCOMPARE(a.count('E'),3);
QCOMPARE(a.count('F'),2);
QCOMPARE(a.count("FG"),2);
-#endif
// QCOMPARE(a.contains(QRegExp("[FG][HI]")),1);
// QCOMPARE(a.contains(QRegExp("[G][HE]")),2);
}
@@ -771,7 +719,6 @@ void tst_Q3CString::replace_uint_uint()
void tst_Q3CString::replace_string()
{
-#if QT_VERSION >= 0x030100
QFETCH( Q3CString, string );
QFETCH( Q3CString, before );
QFETCH( Q3CString, after );
@@ -788,37 +735,6 @@ void tst_Q3CString::replace_string()
Q3CString s3 = string;
s3.replace( before, after );
QCOMPARE( s3, result );
-
-#if QT_VERSION < 0x040000
- if ( !string.isNull() ) {
- /*
- I've changed the isNull() behavior in QString::replace() in
- Qt 3.2, according to the philosophy that null and empty
- should behave mostly the same.
- */
- Q3CString s4 = string;
- s4.replace( QRegExp(QRegExp::escape(before)), after );
- QVERIFY( s4 == result );
- }
-#endif
-#else
- QSKIP( "Not tested with Qt versions < 3.1", SkipAll);
-#endif
-}
-
-void tst_Q3CString::replace_regexp()
-{
-#if QT_VERSION >= 0x040000
- QSKIP("This functionality has been removed in Qt 4.", SkipAll);
-#else
- QFETCH( Q3CString, string );
- QFETCH( Q3CString, regexp );
- QFETCH( Q3CString, after );
- QFETCH( Q3CString, result );
-
- string.replace( QRegExp(regexp), after );
- QVERIFY( string == result );
-#endif
}
void tst_Q3CString::remove_uint_uint()
diff --git a/tests/auto/q3header/tst_q3header.cpp b/tests/auto/q3header/tst_q3header.cpp
index f0ad9d4..fe290e8 100644
--- a/tests/auto/q3header/tst_q3header.cpp
+++ b/tests/auto/q3header/tst_q3header.cpp
@@ -59,9 +59,7 @@ public slots:
void cleanupTestCase();
private slots:
void bug_setOffset();
-#if QT_VERSION >= 0x040101
void nullStringLabel();
-#endif
private:
Q3Header *testW;
@@ -108,7 +106,6 @@ void tst_Q3Header::bug_setOffset()
QCOMPARE( testW->offset(), offs );
}
-#if QT_VERSION >= 0x040101
// Task 95640
void tst_Q3Header::nullStringLabel()
{
@@ -123,7 +120,6 @@ void tst_Q3Header::nullStringLabel()
QCOMPARE(testW->label(testW->addLabel(QString())), QString());
QCOMPARE(testW->label(testW->addLabel(QString(""))), QString(""));
}
-#endif
QTEST_MAIN(tst_Q3Header)
#include "tst_q3header.moc"
diff --git a/tests/auto/q3ptrlist/tst_q3ptrlist.cpp b/tests/auto/q3ptrlist/tst_q3ptrlist.cpp
index 49b5a3e..c3d8b16 100644
--- a/tests/auto/q3ptrlist/tst_q3ptrlist.cpp
+++ b/tests/auto/q3ptrlist/tst_q3ptrlist.cpp
@@ -92,7 +92,6 @@ void tst_Q3PtrList::cleanup()
void tst_Q3PtrList::replace()
{
-#if QT_VERSION >= 0x030100
Q3PtrList<int> list;
int foo = 4;
list.setAutoDelete( TRUE );
@@ -110,15 +109,10 @@ void tst_Q3PtrList::replace()
int *p = new int(7);
QCOMPARE( list.insert(2, p), (bool)TRUE );
QCOMPARE( list.replace(2, p), (bool)TRUE );
-
-#else
- QSKIP( "Not tested with Qt versions < 3.1", SkipAll);
-#endif
}
void tst_Q3PtrList::replaceStrDeep()
{
-#if QT_VERSION >= 0x030100
Q3StrList list;
const char *str;
@@ -137,14 +131,10 @@ void tst_Q3PtrList::replaceStrDeep()
QCOMPARE( list.insert(2, str), (bool)TRUE );
QCOMPARE( list.replace(2, str), (bool)TRUE );
-#else
- QSKIP( "Not tested with Qt versions < 3.1", SkipAll);
-#endif
}
void tst_Q3PtrList::replaceStrShallow()
{
-#if QT_VERSION >= 0x030100
Q3StrList list( FALSE );
char str1[] = "This is string 1";
char str2[] = "This is string 2";
@@ -166,9 +156,6 @@ void tst_Q3PtrList::replaceStrShallow()
QCOMPARE( list.insert(2, str), (bool)TRUE );
QCOMPARE( list.replace(2, str), (bool)TRUE );
-#else
- QSKIP( "Not tested with Qt versions < 3.1", SkipAll);
-#endif
}
void tst_Q3PtrList::take()
diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
index 2f88367..2d91186 100644
--- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
+++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
@@ -89,7 +89,7 @@ private slots:
void unicode();
void precision_data() { generic_data(); }
void precision();
- void insertORA_data();
+ void insertORA_data() { generic_data("QOCI"); }
void insertORA();
void batchInsert_data() { generic_data(); }
void batchInsert();
@@ -101,7 +101,7 @@ private slots:
void insertFieldNameContainsWS(); // For task 117996
private:
- void generic_data();
+ void generic_data(const QString &engine=QString());
void createTestTables( QSqlDatabase db );
void dropTestTables( QSqlDatabase db );
void populateTestTables( QSqlDatabase db );
@@ -117,10 +117,14 @@ tst_Q3SqlCursor::~tst_Q3SqlCursor()
{
}
-void tst_Q3SqlCursor::generic_data()
+void tst_Q3SqlCursor::generic_data(const QString &engine)
{
- if ( dbs.fillTestTable() == 0 )
- QSKIP( "No database drivers are available in this Qt configuration", SkipAll );
+ if ( dbs.fillTestTable(engine) == 0 ) {
+ if(engine.isEmpty())
+ QSKIP( "No database drivers are available in this Qt configuration", SkipAll );
+ else
+ QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll );
+ }
}
void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
@@ -297,9 +301,9 @@ void tst_Q3SqlCursor::insert()
// check that primeInsert returns a valid QSqlRecord
QCOMPARE( (int)irec->count(), 4 );
if ( ( irec->field( 0 ).type() != QVariant::Int ) &&
- ( irec->field( 0 ).type() != QVariant::Double ) ) {
+ ( irec->field( 0 ).type() != QVariant::String ) ) {
QFAIL( QString( "Wrong datatype %1 for field 'ID'"
- " (expected Int or Double)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) );
+ " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) );
}
QCOMPARE( QVariant::typeToName( irec->field( 1 ).type() ), QVariant::typeToName( QVariant::String ) );
QCOMPARE( QVariant::typeToName( irec->field( 2 ).type() ), QVariant::typeToName( QVariant::String ) );
@@ -429,12 +433,6 @@ static QString dumpUtf8( const QString& str )
return res;
}
-void tst_Q3SqlCursor::insertORA_data()
-{
- if ( dbs.fillTestTable( "QOCI" ) == 0 )
- QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll );
-}
-
void tst_Q3SqlCursor::insertORA()
{
QFETCH( QString, dbName );
diff --git a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp
index a8c5940..9ab74f0 100644
--- a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp
+++ b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp